aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk4
-rw-r--r--README.md4
-rw-r--r--annotations/build.gradle11
-rw-r--r--annotations/src/main/java/org/robolectric/annotation/Config.java17
-rw-r--r--build.gradle22
-rw-r--r--buildSrc/build.gradle7
-rw-r--r--buildSrc/src/main/groovy/CheckApiChangesPlugin.groovy33
-rw-r--r--buildSrc/src/main/groovy/RoboJavaModulePlugin.groovy10
-rw-r--r--buildSrc/src/main/groovy/ShadowsPlugin.groovy22
-rw-r--r--errorprone/build.gradle14
-rw-r--r--errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/DeprecatedMethodsCheck.java192
-rw-r--r--errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/RobolectricShadow.java124
-rw-r--r--errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/ShadowUsageCheck.java648
-rw-r--r--errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/DeprecatedMethodsCheckTest.java86
-rw-r--r--errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/RobolectricShadowTest.java38
-rw-r--r--errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/ShadowUsageCheckTest.java68
-rw-r--r--errorprone/src/test/java/xxx/XShadowAlertDialog.java14
-rw-r--r--errorprone/src/test/java/xxx/XShadowApplication.java12
-rw-r--r--errorprone/src/test/java/xxx/XShadowConnectivityManager.java17
-rw-r--r--errorprone/src/test/java/xxx/XShadowDialog.java14
-rw-r--r--errorprone/src/test/java/xxx/XShadowLooper.java23
-rw-r--r--errorprone/src/test/java/xxx/XShadowNetworkInfo.java13
-rw-r--r--errorprone/src/test/java/xxx/XShadowPopupMenu.java14
-rw-r--r--errorprone/src/test/java/xxx/XShadows.java32
-rw-r--r--gradle.properties7
-rw-r--r--gradle/wrapper/gradle-wrapper.jarbin54708 -> 56177 bytes
-rw-r--r--integration_tests/androidx_test/build.gradle36
-rw-r--r--integration_tests/androidx_test/src/test/java/org/robolectric/integration_tests/axt/ActivityScenarioTest.java120
-rw-r--r--integration_tests/ctesque/AndroidManifest.xml4
-rw-r--r--integration_tests/ctesque/build.gradle35
-rw-r--r--integration_tests/ctesque/src/test/java/android/content/pm/PackageManagerTest.java49
-rw-r--r--integration_tests/ctesque/src/test/java/android/content/res/AssetManagerTest.java7
-rw-r--r--integration_tests/ctesque/src/test/java/android/content/res/ResourcesTest.java60
-rw-r--r--integration_tests/ctesque/src/test/java/android/graphics/BitmapTest.java46
-rw-r--r--integration_tests/ctesque/src/test/java/android/graphics/MatrixTest.java125
-rw-r--r--integration_tests/ctesque/src/test/java/android/graphics/PathTest.java117
-rw-r--r--integration_tests/ctesque/src/test/java/android/view/MotionEventTest.java50
-rw-r--r--integration_tests/dependency-on-stubs/build.gradle15
-rw-r--r--integration_tests/libphonenumber/build.gradle13
-rw-r--r--integration_tests/mockito-experimental/build.gradle13
-rw-r--r--integration_tests/mockito/build.gradle13
-rw-r--r--integration_tests/multidex/src/test/AndroidManifest.xml16
-rw-r--r--integration_tests/multidex/src/test/java/org/robolectric/integration_tests/multidex/MultiDexTest.java17
-rw-r--r--integration_tests/multidex/src/test/java/org/robolectric/integration_tests/multidex/robolectric.properties3
-rw-r--r--integration_tests/powermock/build.gradle19
-rw-r--r--junit/build.gradle15
-rw-r--r--processor/build.gradle36
-rw-r--r--processor/src/main/java/org/robolectric/annotation/processing/validator/ImplementsValidator.java53
-rw-r--r--processor/src/main/java/org/robolectric/annotation/processing/validator/SdkStore.java102
-rw-r--r--resources/build.gradle23
-rw-r--r--resources/src/main/java/org/robolectric/RoboSettings.java20
-rw-r--r--resources/src/main/java/org/robolectric/manifest/AndroidManifest.java16
-rw-r--r--resources/src/main/java/org/robolectric/manifest/BroadcastReceiverData.java5
-rw-r--r--resources/src/main/java/org/robolectric/manifest/ContentProviderData.java30
-rw-r--r--resources/src/main/java/org/robolectric/manifest/ServiceData.java5
-rw-r--r--resources/src/main/java/org/robolectric/res/android/AConfiguration.java12
-rw-r--r--resources/src/main/java/org/robolectric/res/android/Asset.java160
-rw-r--r--resources/src/main/java/org/robolectric/res/android/AssetDir.java14
-rw-r--r--resources/src/main/java/org/robolectric/res/android/AttributeResolution9.java16
-rw-r--r--resources/src/main/java/org/robolectric/res/android/ByteBucketArray.java9
-rw-r--r--resources/src/main/java/org/robolectric/res/android/Chunk.java4
-rw-r--r--resources/src/main/java/org/robolectric/res/android/ConfigDescription.java22
-rw-r--r--resources/src/main/java/org/robolectric/res/android/CppApkAssets.java10
-rw-r--r--resources/src/main/java/org/robolectric/res/android/CppAssetManager.java124
-rw-r--r--resources/src/main/java/org/robolectric/res/android/CppAssetManager2.java54
-rw-r--r--resources/src/main/java/org/robolectric/res/android/DynamicRefTable.java10
-rw-r--r--resources/src/main/java/org/robolectric/res/android/Errors.java2
-rw-r--r--resources/src/main/java/org/robolectric/res/android/Idmap.java10
-rw-r--r--resources/src/main/java/org/robolectric/res/android/IdmapEntries.java2
-rw-r--r--resources/src/main/java/org/robolectric/res/android/LoadedArsc.java12
-rw-r--r--resources/src/main/java/org/robolectric/res/android/LocaleData.java2
-rw-r--r--resources/src/main/java/org/robolectric/res/android/LocaleDataTables.java180
-rw-r--r--resources/src/main/java/org/robolectric/res/android/ResStringPool.java54
-rw-r--r--resources/src/main/java/org/robolectric/res/android/ResStringPoolHeader.java2
-rw-r--r--resources/src/main/java/org/robolectric/res/android/ResTable.java461
-rw-r--r--resources/src/main/java/org/robolectric/res/android/ResTableTheme.java4
-rw-r--r--resources/src/main/java/org/robolectric/res/android/ResTable_config.java164
-rw-r--r--resources/src/main/java/org/robolectric/res/android/ResourceTypes.java66
-rw-r--r--resources/src/main/java/org/robolectric/res/android/ResourceUtils.java8
-rw-r--r--resources/src/main/java/org/robolectric/res/android/String8.java56
-rw-r--r--resources/src/main/java/org/robolectric/res/android/StringPoolRef.java2
-rw-r--r--resources/src/test/java/org/robolectric/RoboSettingsTest.java18
-rw-r--r--robolectric/Android.mk15
-rw-r--r--robolectric/build.gradle41
-rw-r--r--robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java5
-rw-r--r--robolectric/src/main/java/org/robolectric/SdkPicker.java35
-rw-r--r--robolectric/src/main/java/org/robolectric/android/fakes/RoboMonitoringInstrumentation.java18
-rw-r--r--robolectric/src/main/java/org/robolectric/android/internal/LocalActivityInvoker.java190
-rw-r--r--robolectric/src/main/java/org/robolectric/android/internal/NoOpThreadChecker.java15
-rw-r--r--robolectric/src/main/java/org/robolectric/android/internal/ParallelUniverse.java21
-rw-r--r--robolectric/src/main/java/org/robolectric/internal/dependency/MavenDependencyResolver.java16
-rw-r--r--robolectric/src/main/resources/META-INF/services/androidx.test.internal.platform.ThreadChecker1
-rw-r--r--robolectric/src/main/resources/META-INF/services/androidx.test.internal.platform.app.ActivityInvoker1
-rw-r--r--robolectric/src/test/java/org/robolectric/AttributeSetBuilderTest.java7
-rw-r--r--robolectric/src/test/java/org/robolectric/IncludedDependenciesTest.java3
-rw-r--r--robolectric/src/test/java/org/robolectric/InvokeDynamicTest.java3
-rw-r--r--robolectric/src/test/java/org/robolectric/ManifestFactoryTest.java29
-rw-r--r--robolectric/src/test/java/org/robolectric/QualifiersTest.java8
-rw-r--r--robolectric/src/test/java/org/robolectric/RobolectricTest.java6
-rw-r--r--robolectric/src/test/java/org/robolectric/RobolectricTestRunnerClassLoaderConfigTest.java3
-rw-r--r--robolectric/src/test/java/org/robolectric/RobolectricTestRunnerSelfTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/TemporaryBindingsTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/TestRunnerSequenceTest.java1
-rw-r--r--robolectric/src/test/java/org/robolectric/android/AndroidInterceptorsIntegrationTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/android/AndroidTranslatorClassInstrumentedTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/android/BootstrapTest.java23
-rw-r--r--robolectric/src/test/java/org/robolectric/android/DefaultPackageManagerIntentComparatorTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/android/DeviceConfigTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/android/DrawableResourceLoaderTest.java27
-rw-r--r--robolectric/src/test/java/org/robolectric/android/FragmentTestUtilTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/android/PreferenceIntegrationTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/android/ResourceLoaderTest.java24
-rw-r--r--robolectric/src/test/java/org/robolectric/android/ResourceTableFactoryIntegrationTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/android/ShadowingTest.java15
-rw-r--r--robolectric/src/test/java/org/robolectric/android/XmlResourceParserImplTest.java36
-rw-r--r--robolectric/src/test/java/org/robolectric/android/controller/ActivityControllerTest.java27
-rw-r--r--robolectric/src/test/java/org/robolectric/android/controller/BackupAgentControllerTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/android/controller/ContentProviderControllerTest.java18
-rw-r--r--robolectric/src/test/java/org/robolectric/android/controller/FragmentControllerTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/android/controller/IntentServiceControllerTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/android/controller/ServiceControllerTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/android/internal/ParallelUniverseCreateApplicationTest.java11
-rw-r--r--robolectric/src/test/java/org/robolectric/android/internal/ParallelUniverseTest.java7
-rw-r--r--robolectric/src/test/java/org/robolectric/android/util/concurrent/RoboExecutorServiceTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/fakes/RoboCursorTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/fakes/RoboMenuItemTest.java22
-rw-r--r--robolectric/src/test/java/org/robolectric/fakes/RoboMenuTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/fakes/RoboWebSettingsTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/internal/DefaultManifestFactoryTest.java2
-rw-r--r--robolectric/src/test/java/org/robolectric/internal/dependency/MavenDependencyResolverTest.java6
-rw-r--r--robolectric/src/test/java/org/robolectric/json/JSONArrayTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/junit/rules/ExpectedLogMessagesRuleTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/manifest/AndroidManifestTest.java6
-rw-r--r--robolectric/src/test/java/org/robolectric/res/ResourceParserTest.java21
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/AdapterViewBehavior.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ConverterTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/LegacyManifestParserTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ResourceHelperTest.java8
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/SQLiteCursorTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/SQLiteDatabaseTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/SQLiteOpenHelperTest.java53
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/SQLiteQueryBuilderTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/SQLiteStatementTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSeekBarTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSpinnerAdapterViewBehaviorTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSpinnerTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAbsoluteLayoutTest.java20
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAbstractCursorTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityEventTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityManagerTest.java19
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityNodeInfoTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityServiceTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityWindowInfoTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAccountManagerTest.java72
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAccountTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowActivityGroupTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowActivityManagerTest.java18
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowActivityTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAlarmManagerTest.java37
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAlertDialogTest.java42
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAnimationSetTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAnimationUtilsTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAppOpsManagerTest.java116
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAppTaskTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetHostTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetHostViewTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetManagerTest.java31
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowApplicationTest.java202
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowArrayAdapterTest.java37
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAssetManagerTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncQueryHandlerTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncTaskLoaderTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncTaskTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAudioEffectTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAudioManagerTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAutoCompleteTextViewTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBackupManagerTest.java20
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBaseAdapterTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBatteryManagerTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBinderTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapDrawableTest.java20
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapFactoryTest.java72
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapRegionDecoderTest.java17
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapTest.java59
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothAdapterTest.java22
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothDeviceTest.java17
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothGattTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothManagerTest.java20
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothSocketTest.java44
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBroadcastPendingResultTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBuildTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBundleTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCameraCharacteristicsTest.java47
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCameraManagerTest.java114
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCameraParametersTest.java68
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCameraSizeTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCameraTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCanvasTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCaptioningManagerTest.java60
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCarrierConfigManagerTest.java57
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCheckBoxTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCheckedTextViewTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowChoreographerTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowClipboardManagerTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowColorTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowConfigurationTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowConnectivityManagerTest.java164
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContentObserverTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderClientTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderOperationBuilderTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderOperationTest.java8
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderResultTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContentResolverTest.java21
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContentUrisTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContentValuesTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContextImplTest.java61
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContextTest.java35
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContextWrapperTest.java38
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCookieManagerTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCookieSyncManagerTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCornerPathEffectTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCountDownTimerTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCountingAdapter.java5
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCursorAdapterTest.java11
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCursorWindowTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowCursorWrapperTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDatabaseUtilsTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDateFormatTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDateIntervalFormatTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDatePickerDialogTest.java19
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDateUtilsTest.java36
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDebugTest.java21
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDevicePolicyManagerTest.java35
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDialogPreferenceTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDialogTest.java52
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDiscoverySessionTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDisplayManagerTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDisplayTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDownloadManagerTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDrawableTest.java50
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowDropBoxManagerTest.java11
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowEditTextPreferenceTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowEditTextTest.java19
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowEnvironmentTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowEuiccManagerTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowEventLogTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowExpandableListViewTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowFilterTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowFingerprintManagerTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowFrameLayoutTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowGLES20Test.java30
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowGeocoderTest.java23
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowGestureDetectorTest.java130
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowGradientDrawableTest.java6
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowHandlerTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowHandlerThreadTest.java11
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowHtmlTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowHttpResponseCacheTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowICUTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowIconTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowImageViewTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowInputDeviceTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowInputEventTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowInputMethodManagerTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowIntentFilterAuthorityEntryTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowIntentFilterTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowIntentServiceTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowIntentTest.java34
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowIoUtilsTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowJobSchedulerTest.java132
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowJobServiceTest.java8
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowJsPromptResultTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowJsResultTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowJsonReaderTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowKeyCharacterMapTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowKeyguardManagerTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowLayerDrawableTest.java35
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutAnimationControllerTest.java11
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutInflaterTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutParamsTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowLinearLayoutTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowLinkMovementMethodTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowListPopupWindowTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowListPreferenceTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowListViewAdapterViewBehaviorTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowListViewTest.java44
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowLocaleDataTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowLocationManagerTest.java69
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowLogTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowLooperTest.java34
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowLruTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMarginLayoutParamsTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMatrixCursorTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMatrixTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMediaMetadataRetrieverTest.java17
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMediaPlayerTest.java24
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMediaRecorderTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMediaRouterTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMediaSessionTest.java21
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMediaStoreTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMergeCursorTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMessageQueueTest.java38
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMessageTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMessengerTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMimeTypeMapTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMotionEventTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkInfoTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkScoreManagerTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowNfcAdapterTest.java19
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationBuilder25Test.java14
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationBuilderTest.java19
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationManagerTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowNumberPickerTest.java10
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowObjectAnimatorTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowOpenGLMatrixTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowOutlineTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowOverScrollerTest.java11
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPackageInstallerTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPackageManagerTest.java425
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPaintTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPairTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowParcelFileDescriptorTest.java72
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowParcelTest.java8
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPasswordTransformationMethodTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPathTest.java26
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPeerHandleTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPendingIntentTest.java23
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPhoneWindowTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPictureTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPopupMenuTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPorterDuffColorFilterTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPowerManagerTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceActivityTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceActivityTestWithFragment.java11
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceGroupTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowProcessTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowProgressBarTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowProgressDialogTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowRadioButtonTest.java31
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowRadioGroupTest.java16
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowRatingBarTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowRectTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowRelativeLayoutTest.java17
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowRemoteCallbackListTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowRenderNodeAnimatorTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowResolveInfoTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowResourcesTest.java41
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowRestrictionsManagerTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowResultReceiverTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSQLiteConnectionTest.java20
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowScaleGestureDetectorTest.java17
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowScanResultTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowScrollViewTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowScrollerTest.java11
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSeekBarTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSensorManagerTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSensorTest.java8
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowServiceTest.java23
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSettingsTest.java166
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowShapeDrawableTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSharedMemoryTest.java8
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSharedPreferencesTest.java23
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowShortcutManagerTest.java11
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSimpleCursorAdapterTest.java34
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSliceManagerTest.java71
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSmsManagerTest.java15
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSoundPoolTest.java111
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSpannableStringTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSpannedStringTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSslErrorHandlerTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowStatFsTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowStateListDrawableTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowStaticLayoutTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowStatusBarManagerTest.java60
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowStorageManagerTest.java35
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowStrictModeTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSubscriptionManagerTest.java129
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSurfaceTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSurfaceViewTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSyncResultTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSystemClockTest.java25
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSystemPropertiesTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTabActivityTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTabHostTest.java47
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTabSpecTest.java51
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTelecomManagerTest.java66
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyManagerTest.java52
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyTest.java45
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTextPaintTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTextToSpeechTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTextUtilsTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTextViewTest.java35
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowThemeTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTileServiceTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTileTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTimePickerDialogTest.java11
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTimeTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTimeZoneFinderTest.java14
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowToastTest.java65
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTouchDelegateTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTrafficStatsTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTypedArrayTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTypefaceTest.java14
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowUriTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowUsageStatsManagerTest.java88
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowUsbManagerTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowUserManagerTest.java135
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowValueAnimatorTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowVibratorTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowVideoViewTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowViewAnimatorTest.java8
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowViewConfigurationTest.java28
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowViewFlipperTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowViewGroupTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowViewTest.java72
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowVisualVoicemailSmsTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowWallpaperManagerTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowWebStorageTest.java16
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowWebViewTest.java139
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowWifiConfigurationTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowWifiInfoTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowWifiManagerTest.java145
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowWifiP2pManagerTest.java17
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowWindowManagerGlobalTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowWindowManagerImplTest.java70
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowWindowTest.java17
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/VelocityTrackerTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ViewInnerTextTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ViewStubTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/XmlPullParserTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/util/SQLiteLibraryLoaderTest.java4
-rw-r--r--robolectric/src/test/resources/AndroidManifest.xml7
-rw-r--r--robolectric/src/test/resources/TestAndroidManifestWithContentProviders.xml3
-rw-r--r--robolectric/src/test/resources/TestAndroidManifestWithReceivers.xml2
-rw-r--r--robolectric/src/test/resources/TestAndroidManifestWithServices.xml2
-rw-r--r--robolectric/src/test/resources/res/values/ids.xml4
-rw-r--r--robolectric/src/test/resources/res/values/plurals.xml6
-rw-r--r--robolectric/src/test/resources/resources.ap_bin223830 -> 223838 bytes
-rw-r--r--sandbox/build.gradle27
-rw-r--r--sandbox/src/main/java/org/robolectric/internal/bytecode/ClassInstrumentor.java27
-rw-r--r--sandbox/src/main/java/org/robolectric/internal/bytecode/InvocationProfile.java6
-rw-r--r--sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowMap.java54
-rw-r--r--sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowWrangler.java1
-rwxr-xr-xscripts/build-resources.rb34
-rwxr-xr-xscripts/build-resources.sh3
-rwxr-xr-xscripts/install-dependencies.rb17
-rwxr-xr-xscripts/update-cpp.sh20
-rw-r--r--shadowapi/build.gradle14
-rw-r--r--shadows/androidx/fragment/Android.mk2
-rw-r--r--shadows/androidx/fragment/src/test/java/org/robolectric/shadows/androidx/fragment/FragmentControllerTest.java6
-rw-r--r--shadows/androidx/fragment/src/test/java/org/robolectric/util/TestRunnerWithManifest.java44
-rw-r--r--shadows/framework/build.gradle22
-rw-r--r--shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java7
-rw-r--r--shadows/framework/src/main/java/org/robolectric/android/ConfigurationV25.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/android/controller/ActivityController.java32
-rw-r--r--shadows/framework/src/main/java/org/robolectric/fakes/RoboCursor.java7
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/CachedPathIteratorFactory.java469
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/Converter.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/LegacyManifestParser.java5
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/RoundRectangle.java353
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAbsListView.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAbsSpinner.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityManager.java17
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityNodeInfo.java213
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityRecord.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityService.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityWindowInfo.java30
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccountManager.java135
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivity.java76
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityGroup.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityManager.java23
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityThread.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAdapterView.java3
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlarmManager.java27
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlertDialog.java15
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAnimationUtils.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowApkAssets.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppOpsManager.java149
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetHost.java8
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetHostView.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetManager.java17
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowApplication.java28
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowApplicationPackageManager.java215
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscApkAssets9.java14
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager.java57
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager9.java16
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAsyncTask.java22
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAsyncTaskLoader.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioEffect.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioManager.java41
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBaseAdapter.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBatteryManager.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBinder.java7
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmap.java135
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapDrawable.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapFactory.java24
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapRegionDecoder.java18
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java85
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothDevice.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothGatt.java15
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothManager.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothServerSocket.java1
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothSocket.java54
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBroadcastPendingResult.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBroadcastReceiver.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBuild.java21
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCamera.java156
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCameraCharacteristics.java39
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCameraManager.java52
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCanvas.java51
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCaptioningManager.java19
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCarrierConfigManager.java36
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowChoreographer.java21
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowClipboardManager.java16
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowColor.java14
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowColorMatrixColorFilter.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCompoundButton.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowConnectivityManager.java101
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentObserver.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProvider.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProviderClient.java46
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProviderResult.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentResolver.java150
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentUris.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowContextImpl.java50
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCookieManager.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCookieSyncManager.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCornerPathEffect.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCountDownTimer.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCursorWindow.java66
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowCursorWrapper.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowDateFormat.java14
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowDatePickerDialog.java19
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowDebug.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowDevicePolicyManager.java71
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowDialog.java8
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowDiscoverySession.java1
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplay.java24
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayListCanvas.java30
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowDownloadManager.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowDrawable.java18
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowEnvironment.java24
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowEuiccManager.java1
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowFilter.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowFloatMath.java10
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowFontFamily.java20
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowGLES20.java30
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowGeocoder.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowGradientDrawable.java10
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowHardwareRenderer.java20
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowHttpResponseCache.java24
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowImageDecoder.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputDevice.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputEvent.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputEventReceiver.java1
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputManager.java3
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowInstrumentation.java16
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowIntentService.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowIoUtils.java11
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowJobScheduler.java12
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowJobService.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowJsResult.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowKeyCharacterMap.java8
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowLegacyApkAssets.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowLegacyAssetManager.java45
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinearGradient.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinkMovementMethod.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinux.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowListPopupWindow.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowLocationManager.java38
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowLog.java58
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowLooper.java15
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMatrix.java251
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaMetadataRetriever.java12
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaPlayer.java333
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaRecorder.java50
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaStore.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMemoryMappedFile.java1
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessage.java21
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessageQueue.java8
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessenger.java8
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMimeTypeMap.java10
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMotionEvent.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowNetwork.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowNetworkInfo.java20
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowNfcAdapter.java14
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowNinePatch.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowNotificationManager.java28
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowNsdManager.java1
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowNumberPicker.java22
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowOpenGLMatrix.java77
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowOutline.java3
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowOverScroller.java28
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageInstaller.java31
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageManager.java67
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageParser.java3
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java75
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowParcel.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowParcelFileDescriptor.java30
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPath.java530
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPathMeasure.java58
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPathParser.java611
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPeerHandle.java1
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPendingIntent.java25
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPicture.java14
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPopupMenu.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPopupWindow.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPorterDuffColorFilter.java20
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPowerManager.java30
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowProcess.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowProgressDialog.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowRecordingCanvas.java29
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowRegion.java7
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowRemoteCallbackList.java20
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowRenderNode.java13
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowResolveInfo.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowResultReceiver.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSQLiteOpenHelper.java3
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowScaleGestureDetector.java11
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowScroller.java22
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSeekBar.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensor.java3
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java22
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowService.java24
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java7
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSharedPreferences.java28
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSliceManager.java80
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSmsManager.java50
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSoundPool.java134
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSslErrorHandler.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowStatFs.java31
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowStateListDrawable.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowStatusBarManager.java37
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowStorageManager.java53
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowStrictModeVmPolicy.java1
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSubscriptionManager.java267
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSurface.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSurfaceView.java5
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemClock.java16
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTabActivity.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTabHost.java32
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelecomManager.java85
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephony.java37
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextToSpeech.java41
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextUtils.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextView.java18
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowThreadedRenderer.java27
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTile.java1
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTileService.java1
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTime.java46
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimePickerDialog.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinder.java3
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTypeface.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsageStatsManager.java54
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java228
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowVMRuntime.java25
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowValueAnimator.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowVectorDrawable.java48
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowVelocityTracker.java16
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowVideoView.java30
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowView.java28
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewAnimator.java10
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewConfiguration.java58
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewGroup.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRenderNode.java204
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRootImpl.java3
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowVisualVoicemailSms.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowWallpaperManager.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebStorage.java18
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebSyncManager.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebView.java36
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebViewDatabase.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiManager.java103
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiP2pManager.java11
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindow.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerImpl.java10
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowZoomButtonsController.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/StorageVolumeBuilder.java101
-rw-r--r--shadows/httpclient/build.gradle17
-rw-r--r--shadows/httpclient/src/main/java/org/robolectric/shadows/ShadowAndroidHttpClient.java42
-rw-r--r--shadows/httpclient/src/main/java/org/robolectric/shadows/httpclient/ShadowDefaultRequestDirector.java8
-rw-r--r--shadows/httpclient/src/test/java/org/robolectric/util/TestRunnerWithManifest.java14
-rw-r--r--shadows/multidex/build.gradle6
-rw-r--r--shadows/playservices/build.gradle13
-rw-r--r--shadows/supportv4/build.gradle17
-rw-r--r--shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowAsyncTaskLoader.java4
-rw-r--r--shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowDrawerLayout.java14
-rw-r--r--shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowLocalBroadcastManager.java8
-rw-r--r--shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowSwipeRefreshLayout.java2
-rw-r--r--shadows/supportv4/src/test/java/org/robolectric/util/TestRunnerWithManifest.java14
-rw-r--r--testapp/build.gradle4
-rw-r--r--testapp/src/main/AndroidManifest.xml10
-rw-r--r--testapp/src/main/java/org/robolectric/DisabledTestActivity.java6
-rw-r--r--testapp/src/main/java/org/robolectric/TestActivity.java6
-rw-r--r--testapp/src/main/res/font/vt323_regular.ttfbin0 -> 153116 bytes
-rw-r--r--testapp/src/main/res/values/ids.xml4
-rw-r--r--testapp/src/main/res/values/plurals.xml10
-rw-r--r--utils/build.gradle16
-rw-r--r--utils/src/main/java/org/robolectric/util/Scheduler.java114
-rw-r--r--utils/src/test/java/org/robolectric/util/SchedulerTest.java51
706 files changed, 14302 insertions, 5964 deletions
diff --git a/Android.mk b/Android.mk
index 83bfef3ce..6d6e3c0a2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -43,9 +43,9 @@ include $(call first-makefiles-under, $(LOCAL_PATH))
##############################################
include $(CLEAR_VARS)
-.PHONY: Run_all_robolectric_tests
+.PHONY: Run_robolectric_test_suite
-Run_all_robolectric_tests: \
+Run_robolectric_test_suite: \
Run_robolectric_utils_tests \
Run_robolectric_sandbox_tests \
Run_robolectric_processor_tests \
diff --git a/README.md b/README.md
index 276e55278..4b3783f12 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ If you'd like to start a new project with Robolectric tests you can refer to `de
#### build.gradle:
```groovy
-testCompile "org.robolectric:robolectric:3.8"
+testImplementation "org.robolectric:robolectric:4.0.2"
```
## Building And Contributing
@@ -66,6 +66,6 @@ repositories {
}
dependencies {
- testCompile "org.robolectric:robolectric:4.0-alpha-4-SNAPSHOT"
+ testImplementation "org.robolectric:robolectric:4.1-SNAPSHOT"
}
```
diff --git a/annotations/build.gradle b/annotations/build.gradle
index f4d2b6042..f1b281f87 100644
--- a/annotations/build.gradle
+++ b/annotations/build.gradle
@@ -1,14 +1,9 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
dependencies {
- // Compile dependencies
- compile project(":shadowapi")
- compileOnly "com.google.code.findbugs:jsr305:3.0.1"
+ api project(":shadowapi")
+ compileOnly "com.google.code.findbugs:jsr305:3.0.2"
compileOnly AndroidSdk.MAX_SDK.coordinates
-} \ No newline at end of file
+}
diff --git a/annotations/src/main/java/org/robolectric/annotation/Config.java b/annotations/src/main/java/org/robolectric/annotation/Config.java
index 2fc82fe5e..d370c59d8 100644
--- a/annotations/src/main/java/org/robolectric/annotation/Config.java
+++ b/annotations/src/main/java/org/robolectric/annotation/Config.java
@@ -1,6 +1,7 @@
package org.robolectric.annotation;
import android.app.Application;
+import android.content.pm.PackageInfo;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
@@ -87,14 +88,22 @@ public @interface Config {
Class<? extends Application> application() default DefaultApplication.class; // DEFAULT_APPLICATION
/**
- * Java package name where the "R.class" file is located. This only needs to be specified if you define
- * an {@code applicationId} associated with {@code productFlavors} or specify {@code applicationIdSuffix}
- * in your build.gradle.
+ * Java package name where the "R.class" file is located. This only needs to be specified if you
+ * define an {@code applicationId} associated with {@code productFlavors} or specify {@code
+ * applicationIdSuffix} in your build.gradle.
*
- * If not specified, Robolectric defaults to the {@code applicationId}.
+ * <p>If not specified, Robolectric defaults to the {@code applicationId}.
*
* @return The java package name for R.class.
+ * @deprecated To change your package name please override the applicationId in your build system.
+ * Changing package name here is broken as the package name will no longer match the package
+ * name encoded in the arsc resources file. If you are looking to simulate another application
+ * you can create another applications Context using {@link
+ * android.content.Context#createPackageContext(String, int)}. Note that you must add this
+ * package to {@link org.robolectric.shadows.ShadowPackageManager#addPackage(PackageInfo)}
+ * first.
*/
+ @Deprecated
String packageName() default DEFAULT_PACKAGE_NAME;
/**
diff --git a/build.gradle b/build.gradle
index 25ac5aa74..ad7f93dba 100644
--- a/build.gradle
+++ b/build.gradle
@@ -4,24 +4,23 @@ buildscript {
repositories {
google()
jcenter()
+ gradlePluginPortal()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.1.0-alpha08'
- classpath 'com.netflix.nebula:gradle-aggregate-javadocs-plugin:2.2.+'
+ classpath 'com.android.tools.build:gradle:3.2.1'
+ classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.6'
+ classpath 'com.netflix.nebula:gradle-aggregate-javadocs-plugin:2.2.1'
classpath 'ch.raffael.pegdown-doclet:pegdown-doclet:1.3'
}
}
-plugins {
- id "net.ltgt.apt" version "0.13" // automatic annotation processing
-}
-
allprojects {
repositories {
mavenLocal()
- jcenter()
google()
+ jcenter()
+ mavenCentral()
}
group = "org.robolectric"
@@ -29,7 +28,6 @@ allprojects {
}
apply plugin: 'idea'
-apply plugin: 'net.ltgt.apt'
project.ext.configAnnotationProcessing = []
project.afterEvaluate {
@@ -100,10 +98,10 @@ task prefetchDependencies() {
doLast {
allprojects.each { p ->
- ['compile', 'runtime', 'testCompile', 'testRuntime'].each { configName ->
- if (p.configurations.findByName(configName)) {
- // causes dependencies to be resolved:
- p.configurations[configName].files
+ p.configurations.each { config ->
+ // causes dependencies to be resolved:
+ if (config.isCanBeResolved()) {
+ config.files
}
}
}
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index 7619b4cae..eede5417b 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -1,3 +1,4 @@
+apply plugin: "java-library"
apply plugin: "groovy"
repositories {
@@ -6,8 +7,8 @@ repositories {
}
dependencies {
- compile gradleApi()
- compile localGroovy()
+ implementation gradleApi()
+ implementation localGroovy()
- compile "org.ow2.asm:asm-tree:5.0.1"
+ implementation "org.ow2.asm:asm-tree:7.0"
}
diff --git a/buildSrc/src/main/groovy/CheckApiChangesPlugin.groovy b/buildSrc/src/main/groovy/CheckApiChangesPlugin.groovy
index b107f6512..c0671c598 100644
--- a/buildSrc/src/main/groovy/CheckApiChangesPlugin.groovy
+++ b/buildSrc/src/main/groovy/CheckApiChangesPlugin.groovy
@@ -9,6 +9,7 @@ import java.util.jar.JarEntry
import java.util.jar.JarInputStream
import java.util.regex.Pattern
+import static org.objectweb.asm.Opcodes.ACC_PRIVATE
import static org.objectweb.asm.Opcodes.ACC_PROTECTED
import static org.objectweb.asm.Opcodes.ACC_PUBLIC
import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC
@@ -295,7 +296,7 @@ class CheckApiChangesPlugin implements Plugin<Project> {
case 'V': write('void'); break;
}
}
- "$methodAccessString $methodNode.name(${args.toString()}): ${returnType.toString()}"
+ "$methodAccessString ${isHiddenApi() ? "@HiddenApi " : ""}${isImplementation() ? "@Implementation " : ""}$methodNode.name(${args.toString()}): ${returnType.toString()}"
}
@Override
@@ -324,21 +325,31 @@ class CheckApiChangesPlugin implements Plugin<Project> {
containsAnnotation(methodNode.visibleAnnotations, "Ljava/lang/Deprecated;")
}
+ boolean isImplementation() {
+ containsAnnotation(methodNode.visibleAnnotations, "Lorg/robolectric/annotation/Implementation;")
+ }
+
+ boolean isHiddenApi() {
+ containsAnnotation(methodNode.visibleAnnotations, "Lorg/robolectric/annotation/HiddenApi;")
+ }
+
String getMethodAccessString() {
- if (bitSet(methodNode.access, ACC_PROTECTED)) {
- return "protected"
- }
- if (bitSet(methodNode.access, ACC_PUBLIC)) {
- return "public"
- }
+ return getAccessString(methodNode.access)
}
- String getClassAccessString() {
- if (bitSet(classNode.access, ACC_PROTECTED)) {
+ private String getClassAccessString() {
+ return getAccessString(classNode.access)
+ }
+
+ String getAccessString(int access) {
+ if (bitSet(access, ACC_PROTECTED)) {
return "protected"
- }
- if (bitSet(classNode.access, ACC_PUBLIC)) {
+ } else if (bitSet(access, ACC_PUBLIC)) {
return "public"
+ } else if (bitSet(access, ACC_PRIVATE)) {
+ return "private"
+ } else {
+ return "[package]"
}
}
diff --git a/buildSrc/src/main/groovy/RoboJavaModulePlugin.groovy b/buildSrc/src/main/groovy/RoboJavaModulePlugin.groovy
index b18ad6628..8a34039e5 100644
--- a/buildSrc/src/main/groovy/RoboJavaModulePlugin.groovy
+++ b/buildSrc/src/main/groovy/RoboJavaModulePlugin.groovy
@@ -9,10 +9,17 @@ class RoboJavaModulePlugin implements Plugin<Project> {
Boolean deploy = false;
Closure doApply = {
- apply plugin: "java"
+ apply plugin: "java-library"
+ apply plugin: "net.ltgt.errorprone"
+
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
+ project.dependencies {
+ errorprone("com.google.errorprone:error_prone_core:$errorproneVersion")
+ errorproneJavac("com.google.errorprone:javac:$errorproneJavacVersion")
+ }
+
tasks.withType(JavaCompile) { task ->
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
@@ -24,7 +31,6 @@ class RoboJavaModulePlugin implements Plugin<Project> {
}
compilerArgs << "-Xlint:-options" // Turn off "missing" bootclasspath warning
encoding = "utf-8" // Make sure source encoding is UTF-8
- incremental = true
}
def noRebuild = System.getenv('NO_REBUILD') == "true"
diff --git a/buildSrc/src/main/groovy/ShadowsPlugin.groovy b/buildSrc/src/main/groovy/ShadowsPlugin.groovy
index 5d38188ef..7374af682 100644
--- a/buildSrc/src/main/groovy/ShadowsPlugin.groovy
+++ b/buildSrc/src/main/groovy/ShadowsPlugin.groovy
@@ -8,28 +8,32 @@ import java.util.jar.JarFile
class ShadowsPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
- project.apply plugin: "net.ltgt.apt"
project.apply plugin: 'idea'
project.extensions.create("shadows", ShadowsPluginExtension)
project.dependencies {
- apt project.project(":processor")
+ annotationProcessor project.project(":processor")
}
def compileJavaTask = project.tasks["compileJava"]
+
+ // write generated Java into its own dir... see https://github.com/gradle/gradle/issues/4956
+ def generatedSrcRelPath = 'build/generated/src/apt/main'
+ def generatedSrcDir = project.file(generatedSrcRelPath)
+
+ project.sourceSets.main.java { srcDir generatedSrcRelPath }
+ project.mkdir(generatedSrcDir)
+ compileJavaTask.options.annotationProcessorGeneratedSourcesDirectory = generatedSrcDir
+ compileJavaTask.outputs.dir(generatedSrcDir)
+
compileJavaTask.doFirst {
options.compilerArgs.add("-Aorg.robolectric.annotation.processing.shadowPackage=${project.shadows.packageName}")
options.compilerArgs.add("-Aorg.robolectric.annotation.processing.sdkCheckMode=${project.shadows.sdkCheckMode}")
}
- // this doesn't seem to have any effect in IDEA yet, unfortunately...
- def aptGeneratedSrcDir = new File(project.buildDir, 'generated/source/apt/main')
- project.idea.module.generatedSourceDirs << aptGeneratedSrcDir
-
- // include generated sources in javadoc and source jars
- project.tasks['javadoc'].source(aptGeneratedSrcDir)
- project.tasks['sourcesJar'].from(project.fileTree(aptGeneratedSrcDir))
+ // include generated sources in javadoc jar
+ project.tasks['javadoc'].source(generatedSrcDir)
// verify that we have the apt-generated files in our javadoc and sources jars
project.tasks['javadocJar'].doLast { task ->
diff --git a/errorprone/build.gradle b/errorprone/build.gradle
index 8707f56c0..78c2d5866 100644
--- a/errorprone/build.gradle
+++ b/errorprone/build.gradle
@@ -1,7 +1,3 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true,
).apply(project)
@@ -20,12 +16,14 @@ dependencies {
compile project(":annotations")
// Compile dependencies
- compile "com.google.errorprone:error_prone_annotation:2.3.1"
- compile "com.google.errorprone:error_prone_refaster:2.3.1"
- compile "com.google.errorprone:error_prone_check_api:2.3.1"
+ compile "com.google.errorprone:error_prone_annotation:2.3.2"
+ compile "com.google.errorprone:error_prone_refaster:2.3.2"
+ compile "com.google.errorprone:error_prone_check_api:2.3.2"
compile "com.google.auto.service:auto-service:1.0-rc4"
compileOnly(AndroidSdk.MAX_SDK.coordinates) { force = true }
+ annotationProcessor "com.google.auto.service:auto-service:1.0-rc4"
+
// in jdk 9, tools.jar disappears!
def toolsJar = org.gradle.internal.jvm.Jvm.current().getToolsJar()
if (toolsJar != null) {
@@ -34,7 +32,7 @@ dependencies {
// Testing dependencies
testCompile "junit:junit:4.12"
- testCompile "com.google.truth:truth:0.36"
+ testCompile "com.google.truth:truth:0.42"
testCompile("com.google.errorprone:error_prone_test_helpers:2.3.1") {
exclude group: 'junit', module: 'junit' // because it depends on a snapshot!?
}
diff --git a/errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/DeprecatedMethodsCheck.java b/errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/DeprecatedMethodsCheck.java
index 52450114c..c028e611b 100644
--- a/errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/DeprecatedMethodsCheck.java
+++ b/errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/DeprecatedMethodsCheck.java
@@ -3,12 +3,15 @@ package org.robolectric.errorprone.bugpatterns;
import static com.google.errorprone.BugPattern.Category.ANDROID;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
import static com.google.errorprone.matchers.Description.NO_MATCH;
+import static com.google.errorprone.matchers.Matchers.instanceMethod;
import static com.google.errorprone.matchers.Matchers.staticMethod;
import static com.google.errorprone.util.ASTHelpers.hasAnnotation;
+import static org.robolectric.errorprone.bugpatterns.Helpers.isCastableTo;
import static org.robolectric.errorprone.bugpatterns.Helpers.isInShadowClass;
import com.google.auto.service.AutoService;
import com.google.errorprone.BugPattern;
+import com.google.errorprone.BugPattern.LinkType;
import com.google.errorprone.BugPattern.ProvidesFix;
import com.google.errorprone.BugPattern.StandardTags;
import com.google.errorprone.VisitorState;
@@ -17,8 +20,7 @@ import com.google.errorprone.bugpatterns.BugChecker.ClassTreeMatcher;
import com.google.errorprone.fixes.Fix;
import com.google.errorprone.fixes.SuggestedFix;
import com.google.errorprone.matchers.Description;
-import com.google.errorprone.matchers.Matcher;
-import com.google.errorprone.matchers.Matchers;
+import com.google.errorprone.matchers.method.MethodMatchers.MethodNameMatcher;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.ImportTree;
import com.sun.source.tree.MethodInvocationTree;
@@ -34,12 +36,11 @@ import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.util.List;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import org.robolectric.annotation.Implements;
-import org.robolectric.errorprone.bugpatterns.ShadowUsageCheck.ShadowInliner;
/** @author christianw@google.com (Christian Williams) */
@AutoService(BugChecker.class)
@@ -50,15 +51,74 @@ import org.robolectric.errorprone.bugpatterns.ShadowUsageCheck.ShadowInliner;
severity = WARNING,
documentSuppression = false,
tags = StandardTags.REFACTORING,
- providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
-public final class DeprecatedMethodsCheck extends BugChecker implements ClassTreeMatcher {
- /** Matches calls to <code>ShadowApplication#getInstance()</code>. */
- private static final Matcher<MethodInvocationTree> shadowAppGetInstanceMatcher =
- Matchers.anyOf(
- staticMethod().onClass("org.robolectric.shadows.ShadowApplication").named("getInstance"),
- staticMethod()
- .onClass("xxx.XShadowApplication") // for tests
- .named("getInstance"));
+ providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION,
+ link = "http://robolectric.org/migrating/#deprecations",
+ linkType = LinkType.CUSTOM)
+public class DeprecatedMethodsCheck extends BugChecker implements ClassTreeMatcher {
+ private final java.util.List<MethodInvocationMatcher> matchers =
+ Arrays.asList(
+ // Matches calls to <code>ShadowApplication.getInstance()</code>.
+ (MethodInvocationMatcher)
+ new MethodInvocationMatcher() {
+ @Override
+ MethodNameMatcher matcher() {
+ return staticMethod()
+ .onClass(shadowName("org.robolectric.shadows.ShadowApplication"))
+ .named("getInstance");
+ }
+
+ @Override
+ void replace(
+ MethodInvocationTree tree,
+ VisitorState state,
+ SuggestedFix.Builder fixBuilder,
+ HashMap<Tree, Runnable> possibleFixes) {
+ MethodCall surroundingMethodCall = getSurroundingMethodCall(tree, state);
+
+ if (surroundingMethodCall != null
+ && surroundingMethodCall.getName().equals("getApplicationContext")) {
+ // transform `ShadowApplication.getInstance().getApplicationContext()`
+ // to `RuntimeEnvironment.application`:
+
+ fixBuilder
+ .replace(surroundingMethodCall.node, "RuntimeEnvironment.application")
+ .addImport("org.robolectric.RuntimeEnvironment");
+ } else {
+ // transform `ShadowApplication.getInstance()`
+ // to `shadowOf(RuntimeEnvironment.application)`:
+ Tree parent = state.getPath().getParentPath().getLeaf();
+ // replaceAssignmentRhs(parent, createSyntheticShadowAccess(state));
+
+ possibleFixes.put(
+ parent,
+ () ->
+ fixBuilder
+ .addImport("org.robolectric.RuntimeEnvironment")
+ .replace(
+ tree,
+ wrapInShadows(
+ state, fixBuilder, "RuntimeEnvironment.application")));
+ }
+ }
+ },
+ new AppGetLastMatcher(
+ "org.robolectric.shadows.ShadowAlertDialog",
+ "ShadowAlertDialog",
+ "getLatestAlertDialog"),
+ new AppGetLastMatcher(
+ "org.robolectric.shadows.ShadowDialog", "ShadowDialog", "getLatestDialog"),
+ new AppGetLastMatcher(
+ "org.robolectric.shadows.ShadowPopupMenu", "ShadowPopupMenu", "getLatestPopupMenu"));
+
+ abstract class MethodInvocationMatcher {
+ abstract MethodNameMatcher matcher();
+
+ abstract void replace(
+ MethodInvocationTree tree,
+ VisitorState state,
+ SuggestedFix.Builder fixBuilder,
+ HashMap<Tree, Runnable> possibleFixes);
+ }
@Override
public Description matchClass(ClassTree tree, VisitorState state) {
@@ -88,41 +148,10 @@ public final class DeprecatedMethodsCheck extends BugChecker implements ClassTre
VisitorState nowState = state.withPath(TreePath.getPath(state.getPath(), tree));
if (!inShadowClass) {
- if (shadowAppGetInstanceMatcher.matches(tree, state)) {
- MethodCall surroundingMethodCall = getSurroundingMethodCall(tree, state);
-
- if (surroundingMethodCall != null
- && surroundingMethodCall.getName().equals("getApplicationContext")) {
- // transform `ShadowApplication.getInstance().getApplicationContext()`
- // to `RuntimeEnvironment.application`:
-
- fixBuilder
- .replace(surroundingMethodCall.node, "RuntimeEnvironment.application")
- .addImport("org.robolectric.RuntimeEnvironment");
- } else {
- // transform `ShadowApplication.getInstance()`
- // to `shadowOf(RuntimeEnvironment.application)`:
- Tree parent = nowState.getPath().getParentPath().getLeaf();
- replaceAssignmentRhs(parent, createSyntheticShadowAccess(state));
-
- // replacements below might be removed, but always add this import...
- fixBuilder
- .addImport("org.robolectric.RuntimeEnvironment")
- .addImport("org.robolectric.Shadows");
-
- Set<String> imports = getImports(state);
- if (imports.contains("org.robolectric.Shadows")) {
- possibleFixes.put(
- parent,
- () ->
- fixBuilder.replace(
- tree, "Shadows.shadowOf(RuntimeEnvironment.application)"));
- } else {
- fixBuilder.addStaticImport("org.robolectric.Shadows.shadowOf");
- possibleFixes.put(
- parent,
- () -> fixBuilder.replace(tree, "shadowOf(RuntimeEnvironment.application)"));
- }
+ for (MethodInvocationMatcher matcher : matchers) {
+ if (matcher.matcher().matches(tree, state)) {
+ matcher.replace(tree, nowState, fixBuilder, possibleFixes);
+ return null;
}
}
}
@@ -132,8 +161,8 @@ public final class DeprecatedMethodsCheck extends BugChecker implements ClassTre
}.scan(tree, state);
if (!fixBuilder.isEmpty() || !possibleFixes.isEmpty()) {
- ShadowInliner shadowInliner = new ShadowInliner(fixBuilder, possibleFixes);
- shadowInliner.scan(tree, state);
+ // ShadowInliner shadowInliner = new ShadowInliner(fixBuilder, possibleFixes);
+ // shadowInliner.scan(tree, state);
}
for (Runnable runnable : possibleFixes.values()) {
@@ -144,6 +173,19 @@ public final class DeprecatedMethodsCheck extends BugChecker implements ClassTre
return fix.isEmpty() ? NO_MATCH : describeMatch(tree, fix);
}
+ private String wrapInShadows(
+ VisitorState state, SuggestedFix.Builder fixBuilder, String content) {
+ Set<String> imports = getImports(state);
+ String shadowyContent;
+ if (imports.contains(shadowName("org.robolectric.Shadows"))) {
+ shadowyContent = shortShadowName("Shadows") + ".shadowOf(" + content + ")";
+ } else {
+ fixBuilder.addStaticImport(shadowName("org.robolectric.Shadows.shadowOf"));
+ shadowyContent = "shadowOf(" + content + ")";
+ }
+ return shadowyContent;
+ }
+
private void replaceAssignmentRhs(Tree parent, JCExpression replacementExpr) {
if (parent instanceof JCFieldAccess) {
JCFieldAccess parentFieldAccess = (JCFieldAccess) parent;
@@ -169,7 +211,8 @@ public final class DeprecatedMethodsCheck extends BugChecker implements ClassTre
treeMaker.Ident(findSymbol(state, "org.robolectric.Shadows")),
findSymbol(state, "org.robolectric.Shadows", "shadowOf(android.app.Application)"));
- JCMethodInvocation callShadowOf = treeMaker.Apply(null, shadowOfApp, List.of(application));
+ JCMethodInvocation callShadowOf =
+ treeMaker.Apply(null, shadowOfApp, com.sun.tools.javac.util.List.of(application));
callShadowOf.type = callShadowOf.meth.type;
return callShadowOf;
}
@@ -227,4 +270,51 @@ public final class DeprecatedMethodsCheck extends BugChecker implements ClassTre
return ((JCFieldAccess) node.getMethodSelect()).name.toString();
}
}
+
+ String shadowName(String className) {
+ return className;
+ }
+
+ String shortShadowName(String shadowClassName) {
+ return shadowClassName;
+ }
+
+ private class AppGetLastMatcher extends MethodInvocationMatcher {
+ private final String methodName;
+ private final String shadowClassName;
+ private final String shadowShortClassName;
+
+ AppGetLastMatcher(
+ String shadowClassName, String shadowShortClassName, String methodName) {
+ this.methodName = methodName;
+ this.shadowClassName = shadowClassName;
+ this.shadowShortClassName = shadowShortClassName;
+ }
+
+ @Override
+ MethodNameMatcher matcher() {
+ return instanceMethod()
+ .onClass(isCastableTo(shadowName("org.robolectric.shadows.ShadowApplication")))
+ .named(methodName);
+ }
+
+ @Override
+ void replace(
+ MethodInvocationTree tree,
+ VisitorState state,
+ SuggestedFix.Builder fixBuilder,
+ HashMap<Tree, Runnable> possibleFixes) {
+ possibleFixes.put(
+ tree,
+ () ->
+ fixBuilder
+ .addImport(shadowName(shadowClassName))
+ .replace(
+ tree,
+ wrapInShadows(
+ state,
+ fixBuilder,
+ shortShadowName(shadowShortClassName) + "." + methodName + "()")));
+ }
+ }
}
diff --git a/errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/RobolectricShadow.java b/errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/RobolectricShadow.java
index 234f36203..da6640a55 100644
--- a/errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/RobolectricShadow.java
+++ b/errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/RobolectricShadow.java
@@ -22,6 +22,7 @@ import com.sun.source.doctree.StartElementTree;
import com.sun.source.doctree.TextTree;
import com.sun.source.tree.AnnotationTree;
import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.ModifiersTree;
@@ -33,6 +34,7 @@ import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.tree.DCTree.DCDocComment;
import com.sun.tools.javac.tree.DCTree.DCReference;
import com.sun.tools.javac.tree.DCTree.DCStartElement;
+import com.sun.tools.javac.tree.JCTree.JCAssign;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import java.util.ArrayList;
import java.util.List;
@@ -65,53 +67,27 @@ public final class RobolectricShadow extends BugChecker implements ClassTreeMatc
List<Optional<SuggestedFix>> fixes = new ArrayList<>();
if (implementsClassMatcher.matches(classTree, state)) {
- JavacTrees trees = JavacTrees.instance(state.context);
+ boolean inSdk = true;
- new TreePathScanner<Void, Void>() {
- @Override
- public Void visitMethod(MethodTree methodTree, Void aVoid) {
- if (implementationMethodMatcher.matches(methodTree, state)) {
- processImplementationMethod(methodTree);
- }
- return super.visitMethod(methodTree, aVoid);
- }
-
- private void processImplementationMethod(MethodTree methodTree) {
- String methodName = methodTree.getName().toString();
- if ("toString".equals(methodName)
- || "equals".equals(methodName)
- || "hashCode".equals(methodName)) {
- return; // they need to remain public
- }
- ModifiersTree modifiersTree = methodTree.getModifiers();
- for (AnnotationTree annotationTree : modifiersTree.getAnnotations()) {
- JCIdent ident = (JCIdent) annotationTree.getAnnotationType();
- if ("java.lang.Override".equals(ident.sym.getQualifiedName().toString())) {
- return; // can't have more restrictive permissions than the overridden method
+ JavacTrees trees = JavacTrees.instance(state.context);
+ for (AnnotationTree annotationTree : classTree.getModifiers().getAnnotations()) {
+ JCIdent ident = (JCIdent) annotationTree.getAnnotationType();
+ String annotationClassName = ident.sym.getQualifiedName().toString();
+ if ("org.robolectric.annotation.Implements".equals(annotationClassName)) {
+ for (ExpressionTree expressionTree : annotationTree.getArguments()) {
+ JCAssign jcAnnotation = (JCAssign) expressionTree;
+ if ("isInAndroidSdk".equals(jcAnnotation.lhs.toString())
+ && "false".equals(jcAnnotation.rhs.toString())) {
+ // shadows of classes not in the public Android SDK can keep their public methods.
+ inSdk = false;
}
}
-
- Set<Modifier> modifiers = modifiersTree.getFlags();
- if (!modifiers.contains(Modifier.PROTECTED)) {
- fixes.add(
- SuggestedFixes.removeModifiers(
- methodTree, state, Modifier.PUBLIC, Modifier.PRIVATE));
- fixes.add(SuggestedFixes.addModifiers(methodTree, state, Modifier.PROTECTED));
- }
-
- if (doScanJavadoc) {
- scanJavadoc();
- }
}
+ }
- private void scanJavadoc() {
- DocCommentTree commentTree = trees.getDocCommentTree(getCurrentPath());
- if (commentTree != null) {
- DocTreePath docTrees = new DocTreePath(getCurrentPath(), commentTree);
- new DocTreeSymbolScanner(trees, fixes).scan(docTrees, null);
- }
- }
- }.scan(state.getPath(), null);
+ if (inSdk) {
+ new ImplementationMethodScanner(state, fixes, trees).scan(state.getPath(), null);
+ }
}
SuggestedFix.Builder builder = SuggestedFix.builder();
@@ -194,4 +170,68 @@ public final class RobolectricShadow extends BugChecker implements ClassTreeMatc
return null;
}
}
+
+ private class ImplementationMethodScanner extends TreePathScanner<Void, Void> {
+
+ private final com.google.errorprone.VisitorState state;
+ private final List<Optional<SuggestedFix>> fixes;
+ private final JavacTrees trees;
+
+ ImplementationMethodScanner(com.google.errorprone.VisitorState state,
+ List<Optional<SuggestedFix>> fixes, JavacTrees trees) {
+ this.state = state;
+ this.fixes = fixes;
+ this.trees = trees;
+ }
+
+ @Override
+ public Void visitMethod(MethodTree methodTree, Void aVoid) {
+ if (implementationMethodMatcher.matches(methodTree, state)) {
+ processImplementationMethod(methodTree);
+ }
+ return super.visitMethod(methodTree, aVoid);
+ }
+
+ private void processImplementationMethod(MethodTree methodTree) {
+ String methodName = methodTree.getName().toString();
+ if ("toString".equals(methodName)
+ || "equals".equals(methodName)
+ || "hashCode".equals(methodName)) {
+ return; // they need to remain public
+ }
+ ModifiersTree modifiersTree = methodTree.getModifiers();
+ for (AnnotationTree annotationTree : modifiersTree.getAnnotations()) {
+ JCIdent ident = (JCIdent) annotationTree.getAnnotationType();
+ String annotationClassName = ident.sym.getQualifiedName().toString();
+ if ("java.lang.Override".equals(annotationClassName)) {
+ // can't have more restrictive permissions than the overridden method.
+ return;
+ }
+ if ("org.robolectric.annotation.HiddenApi".equals(annotationClassName)) {
+ // @HiddenApi implementation methods can stay public for the convenience of tests.
+ return;
+ }
+ }
+
+ Set<Modifier> modifiers = modifiersTree.getFlags();
+ if (!modifiers.contains(Modifier.PROTECTED)) {
+ fixes.add(
+ SuggestedFixes.removeModifiers(
+ methodTree, state, Modifier.PUBLIC, Modifier.PRIVATE));
+ fixes.add(SuggestedFixes.addModifiers(methodTree, state, Modifier.PROTECTED));
+ }
+
+ if (doScanJavadoc) {
+ scanJavadoc();
+ }
+ }
+
+ private void scanJavadoc() {
+ DocCommentTree commentTree = trees.getDocCommentTree(getCurrentPath());
+ if (commentTree != null) {
+ DocTreePath docTrees = new DocTreePath(getCurrentPath(), commentTree);
+ new DocTreeSymbolScanner(trees, fixes).scan(docTrees, null);
+ }
+ }
+ }
}
diff --git a/errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/ShadowUsageCheck.java b/errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/ShadowUsageCheck.java
index c5ecf47c0..7e0cfc5d2 100644
--- a/errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/ShadowUsageCheck.java
+++ b/errorprone/src/main/java/org/robolectric/errorprone/bugpatterns/ShadowUsageCheck.java
@@ -52,6 +52,7 @@ import com.sun.tools.javac.code.Type.UnknownType;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAssign;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCIdent;
@@ -61,9 +62,12 @@ import com.sun.tools.javac.tree.JCTree.JCNewClass;
import com.sun.tools.javac.tree.JCTree.JCTypeCast;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.util.Name;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -85,7 +89,7 @@ import org.robolectric.errorprone.bugpatterns.Helpers.AnnotatedMethodMatcher;
severity = SUGGESTION,
documentSuppression = false,
tags = StandardTags.REFACTORING,
- link = "http://robolectric.org/errorprone-refactorings/",
+ link = "http://robolectric.org/migrating/#improper-use-of-shadows",
linkType = LinkType.CUSTOM,
providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION)
public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatcher {
@@ -108,20 +112,16 @@ public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatch
return NO_MATCH;
}
- final ShadowInliner shadowInliner = new ShadowInliner();
+ final ShadowInliner shadowInliner = new ShadowInliner(
+ (JCCompilationUnit) state.getPath().getCompilationUnit());
shadowInliner.scan(tree, state);
- for (Runnable runnable : shadowInliner.possibleFixes.values()) {
- runnable.run();
- }
-
- Fix fix = shadowInliner.fixBuilder.build();
+ Fix fix = shadowInliner.possibleFixes.getFix();
return fix.isEmpty() ? NO_MATCH : describeMatch(tree, fix);
}
static class ShadowInliner extends TreeScanner<Void, VisitorState> {
- private final SuggestedFix.Builder fixBuilder;
- private final Map<Tree, Runnable> possibleFixes;
+ private final PossibleFixes possibleFixes;
private final Set<String> knownFields = new HashSet<>();
private final Set<String> knownLocalVars = new HashSet<>();
@@ -129,12 +129,11 @@ public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatch
private boolean inShadowClass;
- ShadowInliner() {
- this(SuggestedFix.builder(), new HashMap<>());
+ ShadowInliner(JCCompilationUnit compilationUnit) {
+ this(new PossibleFixes(SuggestedFix.builder(), compilationUnit));
}
- ShadowInliner(SuggestedFix.Builder fixBuilder, Map<Tree, Runnable> possibleFixes) {
- this.fixBuilder = fixBuilder;
+ ShadowInliner(PossibleFixes possibleFixes) {
this.possibleFixes = possibleFixes;
}
@@ -152,234 +151,230 @@ public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatch
switch (parent.getKind()) {
case VARIABLE: // ShadowType shadowType = shadowOf(type);
- {
- // shadow is being assigned to a variable; don't do that!
- JCVariableDecl variableDecl = (JCVariableDecl) parent;
- String oldVarName = variableDecl.getName().toString();
-
- // since it's being declared here, no danger of a collision on this var name...
- knownLocalVars.remove(oldVarName);
-
- String newVarName = pickNewName(shadowOfArg, oldVarName, this);
- varRemapping.put(getSymbol(variableDecl), newVarName);
-
- // ... but be careful not to collide with it later.
- knownLocalVars.add(newVarName);
-
- // replace shadow variable declaration with shadowed type and name
- if (!newVarName.equals(shadowOfArg.toString())) {
- Type shadowedType = getUpperBound(shadowOfArgType, state);
- String shadowedTypeName = SuggestedFixes.prettyType(state, fixBuilder, shadowedType);
- String newAssignment =
- shadowedTypeName + " " + newVarName + " = " + shadowOfArg + ";";
-
- // avoid overlapping replacements:
- if (shadowOfArg instanceof JCMethodInvocation) {
- JCExpression jcExpression = ((JCMethodInvocation) shadowOfArg).meth;
- if (jcExpression instanceof JCFieldAccess) {
- possibleFixes.remove(((JCFieldAccess) jcExpression).selected);
- }
+ {
+ // shadow is being assigned to a variable; don't do that!
+ JCVariableDecl variableDecl = (JCVariableDecl) parent;
+ String oldVarName = variableDecl.getName().toString();
+
+ // since it's being declared here, no danger of a collision on this var name...
+ knownLocalVars.remove(oldVarName);
+
+ String newVarName = pickNewName(shadowOfArg, oldVarName, this);
+ varRemapping.put(getSymbol(variableDecl), newVarName);
+
+ // ... but be careful not to collide with it later.
+ knownLocalVars.add(newVarName);
+
+ // replace shadow variable declaration with shadowed type and name
+ if (!newVarName.equals(shadowOfArg.toString())) {
+ Type shadowedType = getUpperBound(shadowOfArgType, state);
+ String shadowedTypeName =
+ SuggestedFixes.prettyType(state, possibleFixes.fixBuilder, shadowedType);
+ String newAssignment =
+ shadowedTypeName + " " + newVarName + " = " + shadowOfArg + ";";
+
+ // avoid overlapping replacements:
+ if (shadowOfArg instanceof JCMethodInvocation) {
+ JCExpression jcExpression = ((JCMethodInvocation) shadowOfArg).meth;
+ if (jcExpression instanceof JCFieldAccess) {
+ possibleFixes.removeFixFor(((JCFieldAccess) jcExpression).selected);
}
-
- possibleFixes.remove(parent);
- fixBuilder.replace(parent, newAssignment);
- } else {
- possibleFixes.remove(parent);
- fixBuilder.delete(parent);
}
- // replace shadow variable reference with `nonShadowInstance` or
- // `shadowOf(nonShadowInstance)` as appropriate.
- new TreePathScanner<Void, Void>() {
- @Override
- public Void visitIdentifier(IdentifierTree identifierTreeX, Void aVoid) {
- JCIdent identifierTree = (JCIdent) identifierTreeX;
-
- Symbol symbol = getSymbol(identifierTree);
- if (variableDecl.sym.equals(symbol) && !isLeftSideOfAssignment(identifierTree)) {
- TreePath idPath = TreePath.getPath(compilationUnit, identifierTree);
- Tree parent = idPath.getParentPath().getLeaf();
- boolean callDirectlyOnFramework = shouldCallDirectlyOnFramework(idPath);
-
- JCTree replaceNode;
- if (parent instanceof JCFieldAccess && !callDirectlyOnFramework) {
- JCFieldAccess fieldAccess = (JCFieldAccess) parent;
- replaceNode =
- fieldAccess.selected =
- createSyntheticShadowAccess(
- identifierTree, fieldAccess, shadowOfCall, newVarName, state);
- } else {
- identifierTree.name = state.getName(newVarName);
- identifierTree.sym.name = state.getName(newVarName);
- replaceNode = identifierTree;
- }
+ possibleFixes.fixByReplacing(parent, newAssignment);
+ } else {
+ possibleFixes.fixByDeleting(parent);
+ }
- possibleFixes.put(
- replaceNode,
- () -> {
- fixBuilder.replace(
- identifierTree,
- callDirectlyOnFramework
- ? newVarName
- : shadowOfCall.getMethodSelect() + "(" + newVarName + ")");
- });
+ // replace shadow variable reference with `nonShadowInstance` or
+ // `shadowOf(nonShadowInstance)` as appropriate.
+ new TreePathScanner<Void, Void>() {
+ @Override
+ public Void visitIdentifier(IdentifierTree identifierTreeX, Void aVoid) {
+ JCIdent identifierTree = (JCIdent) identifierTreeX;
+
+ Symbol symbol = getSymbol(identifierTree);
+ if (variableDecl.sym.equals(symbol) && !isLeftSideOfAssignment(identifierTree)) {
+ TreePath idPath = TreePath.getPath(compilationUnit, identifierTree);
+ Tree parent = idPath.getParentPath().getLeaf();
+ boolean callDirectlyOnFramework = shouldCallDirectlyOnFramework(idPath);
+
+ JCTree replaceNode;
+ if (parent instanceof JCFieldAccess && !callDirectlyOnFramework) {
+ JCFieldAccess fieldAccess = (JCFieldAccess) parent;
+ JCMethodInvocation newShadowOfCall =
+ createSyntheticShadowAccess(shadowOfCall, newVarName, symbol, state);
+
+ replaceFieldSelected(fieldAccess, newShadowOfCall, state);
+ replaceNode = newShadowOfCall;
+ } else {
+ identifierTree.name = state.getName(newVarName);
+ identifierTree.sym.name = state.getName(newVarName);
+ replaceNode = identifierTree;
}
- return super.visitIdentifier(identifierTree, aVoid);
- }
- private boolean isLeftSideOfAssignment(IdentifierTree identifierTree) {
- Tree parent = getCurrentPath().getParentPath().getLeaf();
- if (parent instanceof AssignmentTree) {
- return identifierTree.equals(((AssignmentTree) parent).getVariable());
- }
- return false;
+ String replaceWith =
+ callDirectlyOnFramework
+ ? newVarName
+ : shadowOfCall.getMethodSelect() + "(" + newVarName + ")";
+
+ possibleFixes.put(
+ replaceNode, possibleFixes.new ReplacementFix(identifierTree, replaceWith));
}
- }.scan(compilationUnit, null);
- }
- break;
+ return super.visitIdentifier(identifierTree, aVoid);
+ }
- case ASSIGNMENT: // this.shadowType = shadowOf(type);
- {
- // shadow is being assigned to a field or variable; don't do that!
- JCAssign assignment = (JCAssign) parent;
- Symbol fieldSymbol = getSymbol(assignment.lhs);
-
- String oldFieldName = assignment.lhs.toString();
- String remappedName = varRemapping.get(fieldSymbol);
-
- // since it's being declared here, no danger of a collision on this var name...
- knownFields.remove(oldFieldName);
-
- String newFieldName =
- remappedName == null ? pickNewName(shadowOfArg, oldFieldName, this) : remappedName;
- varRemapping.put(fieldSymbol, newFieldName);
-
- // ... but be careful not to collide with it later.
- knownLocalVars.add(newFieldName);
-
- // local variable declaration should have been handled above in the VARIABLE case;
- // just strip shadowOf() and assign it to the de-shadowed variable.
- if (fieldSymbol.getKind() == ElementKind.LOCAL_VARIABLE) {
- if (newFieldName.equals(shadowOfArg.toString())) {
- // assigning to self, don't bother
- TreePath assignmentPath = TreePath.getPath(compilationUnit, assignment);
- Tree assignmentParent = assignmentPath.getParentPath().getLeaf();
- if (assignmentParent instanceof ExpressionStatementTree) {
- possibleFixes.remove(assignmentParent);
- fixBuilder.delete(assignmentParent);
- }
- } else {
- possibleFixes.remove(assignment);
- fixBuilder.replace(assignment, newFieldName + " = " + shadowOfArg.toString());
+ private boolean isLeftSideOfAssignment(IdentifierTree identifierTree) {
+ Tree parent = getCurrentPath().getParentPath().getLeaf();
+ if (parent instanceof AssignmentTree) {
+ return identifierTree.equals(((AssignmentTree) parent).getVariable());
}
- break;
+ return false;
}
+ }.scan(compilationUnit, null);
+ }
+ break;
- Symbol shadowOfArgSym = getSymbol(shadowOfArg);
- ElementKind shadowOfArgDomicile =
- shadowOfArgSym == null
- ? ElementKind.OTHER // it's probably an expression, not a var...
- : shadowOfArgSym.getKind();
- boolean namesAreSame = newFieldName.equals(shadowOfArg.toString());
-
- boolean useExistingField =
- shadowOfArgDomicile == ElementKind.FIELD
- && namesAreSame
- && !isMethodParam(ASTHelpers.getSymbol(shadowOfArg), state.getPath());
-
- if (useExistingField) {
- fixVar(fieldSymbol, state, fixBuilder).delete();
-
- ExpressionStatementTree enclosingNode =
- ASTHelpers.findEnclosingNode(
- TreePath.getPath(compilationUnit, parent), ExpressionStatementTree.class);
- if (enclosingNode != null) {
- fixBuilder.delete(enclosingNode);
+ case ASSIGNMENT: // this.shadowType = shadowOf(type);
+ {
+ // shadow is being assigned to a field or variable; don't do that!
+ JCAssign assignment = (JCAssign) parent;
+ Symbol fieldSymbol = getSymbol(assignment.lhs);
+
+ String oldFieldName = assignment.lhs.toString();
+ String remappedName = varRemapping.get(fieldSymbol);
+
+ // since it's being declared here, no danger of a collision on this var name...
+ knownFields.remove(oldFieldName);
+
+ String newFieldName =
+ remappedName == null ? pickNewName(shadowOfArg, oldFieldName, this) : remappedName;
+ varRemapping.put(fieldSymbol, newFieldName);
+
+ // ... but be careful not to collide with it later.
+ knownLocalVars.add(newFieldName);
+
+ // local variable declaration should have been handled above in the VARIABLE case;
+ // just strip shadowOf() and assign it to the de-shadowed variable.
+ if (fieldSymbol.getKind() == ElementKind.LOCAL_VARIABLE) {
+ if (newFieldName.equals(shadowOfArg.toString())) {
+ // assigning to self, don't bother
+ TreePath assignmentPath = TreePath.getPath(compilationUnit, assignment);
+ Tree assignmentParent = assignmentPath.getParentPath().getLeaf();
+ if (assignmentParent instanceof ExpressionStatementTree) {
+ possibleFixes.fixByDeleting(assignmentParent);
}
} else {
- Type shadowedType = getUpperBound(shadowOfArgType, state);
- String shadowedTypeName = SuggestedFixes.prettyType(state, fixBuilder, shadowedType);
- fixVar(fieldSymbol, state, fixBuilder)
- .setName(newFieldName)
- .setTypeName(shadowedTypeName)
- .setRenameUses(false)
- .modify();
-
- String thisStr = "";
- if (((JCAssign) parent).lhs.toString().startsWith("this.")
- || (shadowOfArgDomicile == ElementKind.LOCAL_VARIABLE && namesAreSame)) {
- thisStr = "this.";
- }
+ possibleFixes.fixByReplacing(
+ assignment, newFieldName + " = " + shadowOfArg.toString());
+ }
+ break;
+ }
- possibleFixes.remove(parent);
- fixBuilder.replace(parent, thisStr + newFieldName + " = " + shadowOfArg);
+ Symbol shadowOfArgSym = getSymbol(shadowOfArg);
+ ElementKind shadowOfArgDomicile =
+ shadowOfArgSym == null
+ ? ElementKind.OTHER // it's probably an expression, not a var...
+ : shadowOfArgSym.getKind();
+ boolean namesAreSame = newFieldName.equals(shadowOfArg.toString());
+
+ boolean useExistingField =
+ shadowOfArgDomicile == ElementKind.FIELD
+ && namesAreSame
+ && !isMethodParam(ASTHelpers.getSymbol(shadowOfArg), state.getPath());
+
+ if (useExistingField) {
+ fixVar(fieldSymbol, state, possibleFixes).delete();
+
+ ExpressionStatementTree enclosingNode =
+ ASTHelpers.findEnclosingNode(
+ TreePath.getPath(compilationUnit, assignment), ExpressionStatementTree.class);
+ if (enclosingNode != null) {
+ possibleFixes.fixByDeleting(enclosingNode);
+ }
+ } else {
+ Type shadowedType = getUpperBound(shadowOfArgType, state);
+ String shadowedTypeName =
+ SuggestedFixes.prettyType(state, possibleFixes.fixBuilder, shadowedType);
+ fixVar(fieldSymbol, state, possibleFixes)
+ .setName(newFieldName)
+ .setTypeName(shadowedTypeName)
+ .setRenameUses(false)
+ .modify();
+
+ String thisStr = "";
+ if (assignment.lhs.toString().startsWith("this.")
+ || (shadowOfArgDomicile == ElementKind.LOCAL_VARIABLE && namesAreSame)) {
+ thisStr = "this.";
}
- TreePath containingBlock = findParentOfKind(state, Kind.BLOCK);
- if (containingBlock != null) {
- // replace shadow field reference with `nonShadowInstance` or
- // `shadowOf(nonShadowInstance)` as appropriate.
- new TreePathScanner<Void, Void>() {
- @Override
- public Void visitMemberSelect(MemberSelectTree memberSelectTree, Void aVoid) {
- maybeReplaceFieldRef(memberSelectTree.getExpression());
+ possibleFixes.fixByReplacing(
+ assignment, thisStr + newFieldName + " = " + shadowOfArg);
+ }
- return super.visitMemberSelect(memberSelectTree, aVoid);
- }
+ TreePath containingBlock = findParentOfKind(state, Kind.BLOCK);
+ if (containingBlock != null) {
+ // replace shadow field reference with `nonShadowInstance` or
+ // `shadowOf(nonShadowInstance)` as appropriate.
+ new TreePathScanner<Void, Void>() {
+ @Override
+ public Void visitMemberSelect(MemberSelectTree memberSelectTree, Void aVoid) {
+ maybeReplaceFieldRef(memberSelectTree.getExpression());
- @Override
- public Void visitIdentifier(IdentifierTree identifierTree, Void aVoid) {
- maybeReplaceFieldRef(identifierTree);
+ return super.visitMemberSelect(memberSelectTree, aVoid);
+ }
- return super.visitIdentifier(identifierTree, aVoid);
- }
+ @Override
+ public Void visitIdentifier(IdentifierTree identifierTree, Void aVoid) {
+ maybeReplaceFieldRef(identifierTree);
+
+ return super.visitIdentifier(identifierTree, aVoid);
+ }
- private void maybeReplaceFieldRef(ExpressionTree subject) {
- Symbol symbol = getSymbol(subject);
- if (symbol != null && symbol.getKind() == ElementKind.FIELD) {
- TreePath subjectPath = TreePath.getPath(compilationUnit, subject);
-
- if (symbol.equals(fieldSymbol) && isPartOfMethodInvocation(subjectPath)) {
- String fieldRef =
- subject.toString().startsWith("this.")
- ? "this." + newFieldName
- : newFieldName;
-
- JCTree replaceNode = (JCTree) subject;
- Tree container = subjectPath.getParentPath().getLeaf();
- if (container instanceof JCFieldAccess) {
- replaceNode =
- createSyntheticShadowAccess(
- replaceNode,
- (JCFieldAccess) container,
- shadowOfCall,
- newFieldName,
- state);
- }
-
- String replaceWith =
- shouldCallDirectlyOnFramework(subjectPath)
- ? fieldRef
- : shadowOfCall.getMethodSelect() + "(" + fieldRef + ")";
- possibleFixes.put(
- replaceNode, () -> fixBuilder.replace(subject, replaceWith));
+ private void maybeReplaceFieldRef(ExpressionTree subject) {
+ Symbol symbol = getSymbol(subject);
+ if (symbol != null && symbol.getKind() == ElementKind.FIELD) {
+ TreePath subjectPath = TreePath.getPath(compilationUnit, subject);
+
+ if (symbol.equals(fieldSymbol) && isPartOfMethodInvocation(subjectPath)) {
+ String fieldRef =
+ subject.toString().startsWith("this.")
+ ? "this." + newFieldName
+ : newFieldName;
+
+ JCTree replaceNode = (JCTree) subject;
+ Tree container = subjectPath.getParentPath().getLeaf();
+ if (container instanceof JCFieldAccess) {
+ JCFieldAccess fieldAccess = (JCFieldAccess) container;
+ JCMethodInvocation newShadowOfCall =
+ createSyntheticShadowAccess(shadowOfCall, newFieldName, symbol, state);
+ replaceFieldSelected(fieldAccess, newShadowOfCall, state);
+ replaceNode = newShadowOfCall;
}
+
+ String replaceWith =
+ shouldCallDirectlyOnFramework(subjectPath)
+ ? fieldRef
+ : shadowOfCall.getMethodSelect() + "(" + fieldRef + ")";
+ possibleFixes.put(
+ replaceNode, possibleFixes.new ReplacementFix(subject, replaceWith));
}
}
- }.scan(compilationUnit, null);
- }
+ }
+ }.scan(compilationUnit, null);
}
- break;
+ }
+ break;
case MEMBER_SELECT: // shadowOf(type).method();
- {
- if (shouldCallDirectlyOnFramework(state.getPath())) {
- if (!isInSyntheticShadowAccess(state)) {
- fixBuilder.replace(shadowOfCall, shadowOfArg.toString());
- }
+ {
+ if (shouldCallDirectlyOnFramework(state.getPath())) {
+ if (!isInSyntheticShadowAccess(state)) {
+ possibleFixes.fixByReplacing(shadowOfCall, shadowOfArg.toString());
}
}
- break;
+ }
+ break;
case TYPE_CAST:
System.out.println("WARN: not sure what to do with " + parent.getKind() + ": " + parent);
@@ -391,6 +386,29 @@ public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatch
}
}
+ private void replaceFieldSelected(JCFieldAccess fieldAccess, JCMethodInvocation newShadowOfCall,
+ VisitorState state) {
+ int priorStartPosition = fieldAccess.selected.getStartPosition();
+ int priorEndPosition = getEndPosition(state, fieldAccess.selected);
+
+ fieldAccess.selected = newShadowOfCall;
+
+ newShadowOfCall.pos = priorStartPosition;
+ if (newShadowOfCall.meth instanceof JCIdent) {
+ ((JCIdent) newShadowOfCall.meth).pos = priorStartPosition;
+ }
+ setEndPosition(state, newShadowOfCall, priorEndPosition);
+ }
+
+ private int getEndPosition(VisitorState state, JCTree node) {
+ return state.getEndPosition(node);
+ }
+
+ private void setEndPosition(VisitorState state, JCTree tree, int endPosition) {
+ JCCompilationUnit compilationUnit = (JCCompilationUnit) state.getPath().getCompilationUnit();
+ compilationUnit.endPositions.storeEnd(tree, endPosition);
+ }
+
@Override
public Void visitClass(ClassTree classTree, VisitorState visitorState) {
boolean priorInShadowClass = inShadowClass;
@@ -428,8 +446,9 @@ public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatch
ClassSymbol owner = (ClassSymbol) methodSelect.sym.owner;
ClassType shadowedClass = determineShadowedClassName(owner, nowState);
- String shadowedTypeName = SuggestedFixes.prettyType(state, fixBuilder, shadowedClass);
- fixBuilder.replace(methodSelect.selected, shadowedTypeName);
+ String shadowedTypeName =
+ SuggestedFixes.prettyType(state, possibleFixes.fixBuilder, shadowedClass);
+ possibleFixes.fixByReplacing(methodSelect.selected, shadowedTypeName);
}
if (!inShadowClass && shadowOfMatcher.matches(tree, nowState)) {
@@ -450,24 +469,43 @@ public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatch
}
private static JCMethodInvocation createSyntheticShadowAccess(
- JCTree replaceNode,
- JCFieldAccess fieldAccess,
MethodInvocationTree shadowOfCall,
String newFieldName,
+ Symbol originalSymbol,
VisitorState state) {
TreeMaker treeMaker = state.getTreeMaker();
+ Symbol newSymbol = createSymbol(originalSymbol, state.getName(newFieldName),
+ ((JCExpression) shadowOfCall.getArguments().get(0)).type);
+
+ JCExpression methodSelect = (JCExpression) shadowOfCall.getMethodSelect();
+ if (methodSelect instanceof JCIdent) {
+ // clone so start pos can be changed...
+ methodSelect = treeMaker.Ident(((JCIdent) shadowOfCall.getMethodSelect()).sym);
+ }
JCMethodInvocation callShadowOf =
treeMaker.Apply(
null,
- (JCExpression) shadowOfCall.getMethodSelect(),
- List.of(treeMaker.Ident(state.getName(newFieldName))));
- callShadowOf.type = new UnknownType();
- fieldAccess.selected = callShadowOf;
- callShadowOf.pos = replaceNode.pos;
+ methodSelect,
+ com.sun.tools.javac.util.List.of(createIdent(treeMaker, newSymbol)));
+ callShadowOf.type = ((JCMethodInvocation) shadowOfCall).type;
return callShadowOf;
}
+ private static Symbol createSymbol(Symbol oldSymbol, Name newName, Type newType) {
+ Symbol newSymbol = oldSymbol.clone(oldSymbol.owner);
+ newSymbol.name = newName;
+ newSymbol.type = newType;
+ return newSymbol;
+ }
+
+ private static JCIdent createIdent(TreeMaker treeMaker, Symbol symbol) {
+ JCIdent newFieldIdent = treeMaker.Ident(symbol.name);
+ newFieldIdent.type = symbol.type;
+ newFieldIdent.sym = symbol;
+ return newFieldIdent;
+ }
+
private static boolean isMethodParam(Symbol fieldSymbol, TreePath path) {
JCMethodDecl enclosingMethodDecl = ASTHelpers.findEnclosingNode(path, JCMethodDecl.class);
if (enclosingMethodDecl != null) {
@@ -622,23 +660,23 @@ public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatch
* Renames the given {@link Symbol} and its usages in the current compilation unit to {@code
* newName}.
*/
- static VariableFixer fixVar(Symbol symbol, VisitorState state, Builder fixBuilder) {
- return new VariableFixer(symbol, state, fixBuilder);
+ static VariableFixer fixVar(Symbol symbol, VisitorState state, PossibleFixes possibleFixes) {
+ return new VariableFixer(symbol, state, possibleFixes);
}
private static class VariableFixer {
private final Symbol symbol;
private final VisitorState state;
- private final SuggestedFix.Builder fixBuilder;
+ private final PossibleFixes possibleFixes;
private boolean renameUses = true;
private String newName;
private String newTypeName;
- public VariableFixer(Symbol symbol, VisitorState state, Builder fixBuilder) {
+ public VariableFixer(Symbol symbol, VisitorState state, PossibleFixes possibleFixes) {
this.symbol = symbol;
this.state = state;
- this.fixBuilder = fixBuilder;
+ this.possibleFixes = possibleFixes;
}
VariableFixer setName(String newName) {
@@ -665,7 +703,7 @@ public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatch
// For a lambda parameter without explicit type, it will return null.
String source = state.getSourceForNode(variableTree.getType());
if (newTypeName != null) {
- fixBuilder.replace(variableTree.getType(), newTypeName);
+ possibleFixes.fixByReplacing(variableTree.getType(), newTypeName);
}
if (newName != null && !newName.equals(name)) {
@@ -673,7 +711,7 @@ public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatch
int pos =
((JCTree) variableTree).getStartPosition()
+ state.getSourceForNode(variableTree).indexOf(name, typeLength);
- fixBuilder.replace(pos, pos + name.length(), newName);
+ possibleFixes.fixByReplacing(pos, pos + name.length(), newName);
}
}
@@ -688,7 +726,7 @@ public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatch
@Override
public void visitIdent(JCTree.JCIdent tree) {
if (symbol.equals(getSymbol(tree))) {
- fixBuilder.replace(tree, newName);
+ possibleFixes.fixByReplacing(tree, newName);
}
}
});
@@ -700,7 +738,7 @@ public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatch
@Override
public Void visitVariable(VariableTree variableTree, Void v) {
if (getSymbol(variableTree).equals(symbol)) {
- fixBuilder.delete(variableTree);
+ possibleFixes.fixByDeleting(variableTree);
}
return super.visitVariable(variableTree, v);
@@ -735,4 +773,150 @@ public final class ShadowUsageCheck extends BugChecker implements ClassTreeMatch
private static Tree findParent(Tree node, VisitorState state) {
return TreePath.getPath(state.getPath().getCompilationUnit(), node).getParentPath().getLeaf();
}
+
+ static class PossibleFixes {
+
+ private final Builder fixBuilder;
+ private final JCCompilationUnit compilationUnit;
+ private final Map<Tree, PossibleFix> map = new HashMap<>();
+ private final List<PossibleFix> list = new ArrayList<>();
+
+ public PossibleFixes(Builder builder, JCCompilationUnit compilationUnit) {
+ fixBuilder = builder;
+ this.compilationUnit = compilationUnit;
+ }
+
+ public void put(Tree tree, PossibleFix possibleFix) {
+ if (tree != null) {
+ PossibleFix priorFix = map.put(tree, possibleFix);
+ if (priorFix != null) {
+ list.remove(priorFix);
+ }
+ }
+
+ list.add(possibleFix);
+ }
+
+ public void removeFixFor(Tree tree) {
+ PossibleFix possibleFix = map.remove(tree);
+ list.remove(possibleFix);
+ }
+
+ public void fixByReplacing(Tree tree, String value) {
+ put(tree, new ReplacementFix(tree, value));
+ }
+
+ public void fixByDeleting(Tree tree) {
+ put(tree, new DeletionFix(tree));
+ }
+
+ public void fixByReplacing(int startPos, int endPos, String replaceWith) {
+ put(null, new PositionalReplacementFix(startPos, endPos, replaceWith));
+ }
+
+ public Fix getFix() {
+ for (PossibleFix possibleFix : list) {
+ possibleFix.applyFix(fixBuilder);
+ }
+
+ return fixBuilder.build();
+ }
+
+ abstract class PossibleFix {
+ protected final Tree tree;
+ protected final int startPosition;
+ protected final int endPosition;
+ private final Throwable trace;
+
+ PossibleFix(Tree tree) {
+ this.tree = tree;
+
+ DiagnosticPosition position = (DiagnosticPosition) tree;
+ this.startPosition = position.getStartPosition();
+ this.endPosition = position.getEndPosition(compilationUnit.endPositions);
+
+ this.trace = new RuntimeException();
+ }
+
+ PossibleFix(int startPosition, int endPosition) {
+ this.tree = null;
+
+ this.startPosition = startPosition;
+ this.endPosition = endPosition;
+
+ this.trace = new RuntimeException();
+ }
+
+ abstract void applyFix(Builder fixBuilder);
+
+ @Override
+ public String toString() {
+ return "PossibleFix{"
+ + "tree="
+ + tree
+ + ", startPosition="
+ + startPosition
+ + ", endPosition="
+ + endPosition
+ + '}';
+ }
+ }
+
+ class ReplacementFix extends PossibleFix {
+
+ private final String replaceWith;
+
+ public ReplacementFix(Tree tree, String replaceWith) {
+ super(tree);
+ this.replaceWith = replaceWith;
+ }
+
+ @Override
+ void applyFix(Builder fixBuilder) {
+ fixBuilder.replace(tree, replaceWith);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + " [replace with " + replaceWith + "]";
+ }
+ }
+
+ private class PositionalReplacementFix extends PossibleFix {
+
+ private final String replaceWith;
+
+ public PositionalReplacementFix(int startPos, int endPos, String replaceWith) {
+ super(startPos, endPos);
+ this.replaceWith = replaceWith;
+ }
+
+ @Override
+ void applyFix(Builder fixBuilder) {
+ fixBuilder.replace(startPosition, endPosition, replaceWith);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + " [replace with " + replaceWith + "]";
+ }
+ }
+
+ class DeletionFix extends PossibleFix {
+
+ public DeletionFix(Tree tree) {
+ super(tree);
+ }
+
+ @Override
+ void applyFix(Builder fixBuilder) {
+ fixBuilder.delete(tree);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + " [delete]";
+ }
+ }
+ }
}
diff --git a/errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/DeprecatedMethodsCheckTest.java b/errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/DeprecatedMethodsCheckTest.java
index 1898c7394..9bbbd0090 100644
--- a/errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/DeprecatedMethodsCheckTest.java
+++ b/errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/DeprecatedMethodsCheckTest.java
@@ -1,8 +1,13 @@
package org.robolectric.errorprone.bugpatterns;
+import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
+
import com.google.errorprone.BugCheckerRefactoringTestHelper;
+import com.google.errorprone.BugPattern;
+import com.google.errorprone.BugPattern.ProvidesFix;
import java.io.IOException;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -16,7 +21,8 @@ public class DeprecatedMethodsCheckTest {
@Before
public void setUp() {
this.testHelper =
- BugCheckerRefactoringTestHelper.newInstance(new DeprecatedMethodsCheck(), getClass());
+ BugCheckerRefactoringTestHelper.newInstance(
+ new DeprecatedMethodsCheckForTest(), getClass());
}
@Test
@@ -37,12 +43,11 @@ public class DeprecatedMethodsCheckTest {
"}")
.addOutputLines(
"in/SomeTest.java",
- "import static org.robolectric.Shadows.shadowOf;",
+ "import static xxx.XShadows.shadowOf;",
"",
"import android.content.Context;",
"import org.junit.Test;",
"import org.robolectric.RuntimeEnvironment;",
- "import org.robolectric.Shadows;",
"import xxx.XShadowApplication;", // removable
"",
"public class SomeTest {",
@@ -56,6 +61,49 @@ public class DeprecatedMethodsCheckTest {
}
@Test
+ public void replaceShadowApplicationGetLatestStuff() throws IOException {
+ testHelper
+ .addInputLines(
+ "in/SomeTest.java",
+ "import static xxx.XShadows.shadowOf;",
+ "",
+ "import org.junit.Test;",
+ "import org.robolectric.RuntimeEnvironment;",
+ "import xxx.XShadowApplication;",
+ "import xxx.XShadowAlertDialog;",
+ "import xxx.XShadowDialog;",
+ "import xxx.XShadowPopupMenu;",
+ "",
+ "public class SomeTest {",
+ " @Test void theTest() {",
+ " XShadowAlertDialog ad = shadowOf(RuntimeEnvironment.application).getLatestAlertDialog();",
+ " XShadowDialog d = shadowOf(RuntimeEnvironment.application).getLatestDialog();",
+ " XShadowPopupMenu pm = shadowOf(RuntimeEnvironment.application).getLatestPopupMenu();",
+ " }",
+ "}")
+ .addOutputLines(
+ "in/SomeTest.java",
+ "import static xxx.XShadows.shadowOf;",
+ "",
+ "import org.junit.Test;",
+ "import org.robolectric.RuntimeEnvironment;", // removable
+ "import xxx.XShadowApplication;",
+ "import xxx.XShadowAlertDialog;",
+ "import xxx.XShadowDialog;",
+ "import xxx.XShadowPopupMenu;",
+ "",
+ "public class SomeTest {",
+ " @Test void theTest() {",
+ " XShadowAlertDialog ad = shadowOf(XShadowAlertDialog.getLatestAlertDialog());",
+ " XShadowDialog d = shadowOf(XShadowDialog.getLatestDialog());",
+ " XShadowPopupMenu pm = shadowOf(XShadowPopupMenu.getLatestPopupMenu());",
+ " }",
+ "}")
+ .doTest();
+ }
+
+ @Test
+ @Ignore("multiple-step refactorings not currently supported")
public void inlineShadowVars() throws IOException {
testHelper
.addInputLines(
@@ -71,7 +119,7 @@ public class DeprecatedMethodsCheckTest {
"}")
.addOutputLines(
"in/SomeTest.java",
- "import static org.robolectric.Shadows.shadowOf;",
+ "import static xxx.XShadows.shadowOf;",
"",
"import android.app.Application;",
"import org.junit.Test;",
@@ -82,7 +130,7 @@ public class DeprecatedMethodsCheckTest {
"public class SomeTest {",
" @Test void theTest() {",
" Application application = RuntimeEnvironment.application;",
- " Shadows.shadowOf(application).runBackgroundTasks();",
+ " XShadows.shadowOf(application).runBackgroundTasks();",
" }",
"}")
.doTest();
@@ -95,7 +143,7 @@ public class DeprecatedMethodsCheckTest {
"in/SomeTest.java",
"import android.content.Context;",
"import org.junit.Test;",
- "import org.robolectric.Shadows;",
+ "import xxx.XShadows;",
"import xxx.XShadowApplication;",
"",
"public class SomeTest {",
@@ -110,13 +158,13 @@ public class DeprecatedMethodsCheckTest {
"import android.content.Context;",
"import org.junit.Test;",
"import org.robolectric.RuntimeEnvironment;",
- "import org.robolectric.Shadows;",
"import xxx.XShadowApplication;", // removable
+ "import xxx.XShadows;",
"",
"public class SomeTest {",
" Context application;",
" @Test void theTest() {",
- " Shadows.shadowOf(RuntimeEnvironment.application).runBackgroundTasks();",
+ " XShadows.shadowOf(RuntimeEnvironment.application).runBackgroundTasks();",
" application = RuntimeEnvironment.application;",
" }",
"}")
@@ -124,6 +172,7 @@ public class DeprecatedMethodsCheckTest {
}
@Test
+ @Ignore("multiple-step refactorings not currently supported")
public void useFrameworkMethodWhenAppropriateAfterApplicationSubstitution() throws IOException {
testHelper
.addInputLines(
@@ -147,7 +196,7 @@ public class DeprecatedMethodsCheckTest {
"import android.content.Context;",
"import org.junit.Test;",
"import org.robolectric.RuntimeEnvironment;",
- "import org.robolectric.Shadows;",
+ "import xxx.XShadows;",
"import xxx.XShadowApplication;", // removable
"",
"public class SomeTest {",
@@ -155,9 +204,26 @@ public class DeprecatedMethodsCheckTest {
" @Test void theTest() {",
" application = RuntimeEnvironment.application;",
" application.getMainLooper();",
- " Shadows.shadowOf(application).runBackgroundTasks();",
+ " XShadows.shadowOf(application).runBackgroundTasks();",
" }",
"}")
.doTest();
}
+
+ @BugPattern(
+ name = "DeprecatedMethods",
+ providesFix = ProvidesFix.REQUIRES_HUMAN_ATTENTION,
+ summary = "",
+ severity = WARNING)
+ private static class DeprecatedMethodsCheckForTest extends DeprecatedMethodsCheck {
+ @Override
+ String shadowName(String className) {
+ return className.replaceAll("org\\.robolectric\\..*Shadow", "xxx.XShadow");
+ }
+
+ @Override
+ String shortShadowName(String className) {
+ return className.replaceAll("Shadow", "XShadow");
+ }
+ }
}
diff --git a/errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/RobolectricShadowTest.java b/errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/RobolectricShadowTest.java
index e4b6659b3..a28d21fa1 100644
--- a/errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/RobolectricShadowTest.java
+++ b/errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/RobolectricShadowTest.java
@@ -23,24 +23,28 @@ public class RobolectricShadowTest {
testHelper
.addInputLines(
"in/SomeShadow.java",
+ "import org.robolectric.annotation.HiddenApi;",
"import org.robolectric.annotation.Implementation;",
"import org.robolectric.annotation.Implements;",
"",
"@Implements(Object.class)",
"public class SomeShadow {",
" @Implementation public void publicMethod() {}",
+ " @Implementation @HiddenApi public void publicHiddenMethod() {}",
" @Implementation protected void protectedMethod() {}",
" @Implementation void packageMethod() {}",
" @Implementation private void privateMethod() {}",
"}")
.addOutputLines(
"in/SomeShadow.java",
+ "import org.robolectric.annotation.HiddenApi;",
"import org.robolectric.annotation.Implementation;",
"import org.robolectric.annotation.Implements;",
"",
"@Implements(Object.class)",
"public class SomeShadow {",
" @Implementation protected void publicMethod() {}",
+ " @Implementation @HiddenApi public void publicHiddenMethod() {}",
" @Implementation protected void protectedMethod() {}",
" @Implementation protected void packageMethod() {}",
" @Implementation protected void privateMethod() {}",
@@ -49,6 +53,40 @@ public class RobolectricShadowTest {
}
@Test
+ public void implMethodsNotProtectedForClassesNotInAndroidSdk() throws IOException {
+ testHelper
+ .addInputLines(
+ "in/SomeShadow.java",
+ "import org.robolectric.annotation.HiddenApi;",
+ "import org.robolectric.annotation.Implementation;",
+ "import org.robolectric.annotation.Implements;",
+ "",
+ "@Implements(value = Object.class, isInAndroidSdk = false)",
+ "public class SomeShadow {",
+ " @Implementation public void publicMethod() {}",
+ " @Implementation @HiddenApi public void publicHiddenMethod() {}",
+ " @Implementation protected void protectedMethod() {}",
+ " @Implementation void packageMethod() {}",
+ " @Implementation private void privateMethod() {}",
+ "}")
+ .addOutputLines(
+ "in/SomeShadow.java",
+ "import org.robolectric.annotation.HiddenApi;",
+ "import org.robolectric.annotation.Implementation;",
+ "import org.robolectric.annotation.Implements;",
+ "",
+ "@Implements(value = Object.class, isInAndroidSdk = false)",
+ "public class SomeShadow {",
+ " @Implementation public void publicMethod() {}",
+ " @Implementation @HiddenApi public void publicHiddenMethod() {}",
+ " @Implementation protected void protectedMethod() {}",
+ " @Implementation void packageMethod() {}",
+ " @Implementation private void privateMethod() {}",
+ "}")
+ .doTest();
+ }
+
+ @Test
public void implMethodJavadocShouldBeMarkdown() throws Exception {
testHelper
.addInputLines(
diff --git a/errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/ShadowUsageCheckTest.java b/errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/ShadowUsageCheckTest.java
index c62c068a3..977726846 100644
--- a/errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/ShadowUsageCheckTest.java
+++ b/errorprone/src/test/java/org/robolectric/errorprone/bugpatterns/ShadowUsageCheckTest.java
@@ -27,19 +27,19 @@ public class ShadowUsageCheckTest {
"in/SomeTest.java",
"import android.os.Looper;",
"import org.junit.Test;",
- "import org.robolectric.shadows.ShadowLooper;",
+ "import xxx.XShadowLooper;",
"",
"public class SomeTest {",
" @Test void theTest() {",
" Looper.getMainLooper();",
- " ShadowLooper.getMainLooper();",
+ " XShadowLooper.getMainLooper();",
" }",
"}")
.addOutputLines(
"in/SomeTest.java",
"import android.os.Looper;",
"import org.junit.Test;",
- "import org.robolectric.shadows.ShadowLooper;", // removable
+ "import xxx.XShadowLooper;", // removable
"",
"public class SomeTest {",
" @Test void theTest() {",
@@ -496,7 +496,7 @@ public class ShadowUsageCheckTest {
" @Test void theTest() {",
" linearLayout = new LinearLayout(RuntimeEnvironment.application);",
" linearLayout.getLayoutAnimation().start();",
- " this.linearLayout.getLayoutAnimation().start();",
+ " linearLayout.getLayoutAnimation().start();",
" shadowOf(linearLayout).getGravity();",
" shadowOf(this.linearLayout).getGravity();",
" }",
@@ -550,7 +550,7 @@ public class ShadowUsageCheckTest {
" linearLayout = new LinearLayout(RuntimeEnvironment.application);",
" linearLayout2 = new LinearLayout(RuntimeEnvironment.application);",
" linearLayout2.getLayoutAnimation().start();",
- " this.linearLayout2.getLayoutAnimation().start();",
+ " linearLayout2.getLayoutAnimation().start();",
" shadowOf(linearLayout2).getGravity();",
" shadowOf(this.linearLayout2).getGravity();",
" }",
@@ -563,35 +563,35 @@ public class ShadowUsageCheckTest {
testHelper
.addInputLines(
"in/SomeTest.java",
- "import static org.robolectric.Shadows.shadowOf;",
+ "import static xxx.XShadows.shadowOf;",
"",
"import android.os.Looper;",
"import org.junit.Before;",
"import org.junit.Test;",
"import org.robolectric.RuntimeEnvironment;",
- "import org.robolectric.shadows.ShadowLooper;",
+ "import xxx.XShadowLooper;",
"",
"public class SomeTest {",
- " private ShadowLooper shadowLooper;",
+ " private XShadowLooper XShadowLooper;",
"",
" @Before void setUp() {",
" Looper looper = RuntimeEnvironment.application.getMainLooper();",
- " shadowLooper = shadowOf(looper);",
+ " XShadowLooper = shadowOf(looper);",
" }",
"",
" @Test void theTest() {",
- " shadowLooper.runToEndOfTasks();",
+ " XShadowLooper.runToEndOfTasks();",
" }",
"}")
.addOutputLines(
"out/SomeTest.java",
- "import static org.robolectric.Shadows.shadowOf;",
+ "import static xxx.XShadows.shadowOf;",
"",
"import android.os.Looper;",
"import org.junit.Before;",
"import org.junit.Test;",
"import org.robolectric.RuntimeEnvironment;",
- "import org.robolectric.shadows.ShadowLooper;",
+ "import xxx.XShadowLooper;",
"",
"public class SomeTest {",
" private Looper looper;",
@@ -740,28 +740,28 @@ public class ShadowUsageCheckTest {
testHelper
.addInputLines(
"in/SomeTestHelper.java",
- "import static org.robolectric.Shadows.shadowOf;",
+ "import static xxx.XShadows.shadowOf;",
"",
"import android.os.Looper;",
- "import org.robolectric.shadows.ShadowLooper;",
+ "import xxx.XShadowLooper;",
"",
"public class SomeTestHelper {",
- " private final ShadowLooper theShadowLooper;",
+ " private final XShadowLooper theShadowLooper;",
"",
" SomeTestHelper(Looper looper) {",
" this.theShadowLooper = shadowOf(looper);",
" }",
"",
" boolean moreTasks() {",
- " return theShadowLooper.getScheduler().areAnyRunnable();",
+ " return theShadowLooper.getSchedule().isEmpty();",
" }",
"}")
.addOutputLines(
"in/SomeTestHelper.java",
- "import static org.robolectric.Shadows.shadowOf;",
+ "import static xxx.XShadows.shadowOf;",
"",
"import android.os.Looper;",
- "import org.robolectric.shadows.ShadowLooper;",
+ "import xxx.XShadowLooper;",
"",
"public class SomeTestHelper {",
" private final Looper looper;",
@@ -771,7 +771,7 @@ public class ShadowUsageCheckTest {
" }",
"",
" boolean moreTasks() {",
- " return shadowOf(looper).getScheduler().areAnyRunnable();",
+ " return shadowOf(looper).getSchedule().isEmpty();",
" }",
"}")
.doTest();
@@ -782,36 +782,36 @@ public class ShadowUsageCheckTest {
testHelper
.addInputLines(
"in/SomeTest.java",
- "import static org.robolectric.Shadows.shadowOf;",
+ "import static xxx.XShadows.shadowOf;",
"",
"import android.content.Context;",
"import android.net.ConnectivityManager;",
"import android.net.NetworkInfo;",
"import org.junit.Test;",
"import org.robolectric.RuntimeEnvironment;",
- "import org.robolectric.shadows.ShadowConnectivityManager;",
- "import org.robolectric.shadows.ShadowNetworkInfo;",
+ "import xxx.XShadowConnectivityManager;",
+ "import xxx.XShadowNetworkInfo;",
"",
"public class SomeTest {",
" @Test void theTest() {",
- " ShadowConnectivityManager shadowConnectivityManager =",
+ " XShadowConnectivityManager shadowConnectivityManager =",
" shadowOf((ConnectivityManager) RuntimeEnvironment.application.getSystemService(Context.CONNECTIVITY_SERVICE));",
- " ShadowNetworkInfo shadowActiveNetworkInfo =",
+ " XShadowNetworkInfo shadowActiveNetworkInfo =",
" shadowOf(shadowConnectivityManager.getActiveNetworkInfo());",
" shadowActiveNetworkInfo.setConnectionType(ConnectivityManager.TYPE_MOBILE);",
" }",
"}")
.addOutputLines(
"out/SomeTest.java",
- "import static org.robolectric.Shadows.shadowOf;",
+ "import static xxx.XShadows.shadowOf;",
"",
"import android.content.Context;",
"import android.net.ConnectivityManager;",
"import android.net.NetworkInfo;",
"import org.junit.Test;",
"import org.robolectric.RuntimeEnvironment;",
- "import org.robolectric.shadows.ShadowConnectivityManager;",
- "import org.robolectric.shadows.ShadowNetworkInfo;",
+ "import xxx.XShadowConnectivityManager;",
+ "import xxx.XShadowNetworkInfo;",
"",
"public class SomeTest {",
" @Test void theTest() {",
@@ -911,13 +911,13 @@ public class ShadowUsageCheckTest {
"import android.os.Looper;",
"import org.robolectric.annotation.Implementation;",
"import org.robolectric.annotation.Implements;",
- "import org.robolectric.shadows.ShadowLooper;",
+ "import xxx.XShadowLooper;",
"",
"@Implements(Looper.class)",
- "public class SomeShadow extends ShadowLooper {",
+ "public class SomeShadow extends XShadowLooper {",
" @Implementation",
" public static Looper getMainLooper() {",
- " return ShadowLooper.getMainLooper();",
+ " return XShadowLooper.getMainLooper();",
" }",
"}")
.addOutputLines(
@@ -925,13 +925,13 @@ public class ShadowUsageCheckTest {
"import android.os.Looper;",
"import org.robolectric.annotation.Implementation;",
"import org.robolectric.annotation.Implements;",
- "import org.robolectric.shadows.ShadowLooper;",
+ "import xxx.XShadowLooper;",
"",
"@Implements(Looper.class)",
- "public class SomeShadow extends ShadowLooper {",
+ "public class SomeShadow extends XShadowLooper {",
" @Implementation",
" public static Looper getMainLooper() {",
- " return ShadowLooper.getMainLooper();",
+ " return XShadowLooper.getMainLooper();",
" }",
"}")
.doTest();
@@ -1269,7 +1269,7 @@ public class ShadowUsageCheckTest {
@Test
@Ignore
public void handleStaticMethodRefs() throws IOException {
- // shadowLooper::idle -> looper::idle
+ // XShadowLooper::idle -> looper::idle
}
@Test
diff --git a/errorprone/src/test/java/xxx/XShadowAlertDialog.java b/errorprone/src/test/java/xxx/XShadowAlertDialog.java
new file mode 100644
index 000000000..9713a76ff
--- /dev/null
+++ b/errorprone/src/test/java/xxx/XShadowAlertDialog.java
@@ -0,0 +1,14 @@
+package xxx;
+
+import android.app.AlertDialog;
+import org.robolectric.annotation.Implements;
+
+/**
+ * Fake shadow for testing {@link org.robolectric.errorprone.bugpatterns.DeprecatedMethodsCheck}.
+ */
+@Implements(AlertDialog.class)
+public class XShadowAlertDialog {
+ public static AlertDialog getLatestAlertDialog() {
+ return null;
+ }
+}
diff --git a/errorprone/src/test/java/xxx/XShadowApplication.java b/errorprone/src/test/java/xxx/XShadowApplication.java
index 0049e61d4..28728a298 100644
--- a/errorprone/src/test/java/xxx/XShadowApplication.java
+++ b/errorprone/src/test/java/xxx/XShadowApplication.java
@@ -20,6 +20,18 @@ public class XShadowApplication {
return null;
}
+ public XShadowAlertDialog getLatestAlertDialog() {
+ return null;
+ }
+
+ public XShadowDialog getLatestDialog() {
+ return null;
+ }
+
+ public XShadowPopupMenu getLatestPopupMenu() {
+ return null;
+ }
+
@Implementation
public Looper getMainLooper() {
return null;
diff --git a/errorprone/src/test/java/xxx/XShadowConnectivityManager.java b/errorprone/src/test/java/xxx/XShadowConnectivityManager.java
new file mode 100644
index 000000000..c6da432c6
--- /dev/null
+++ b/errorprone/src/test/java/xxx/XShadowConnectivityManager.java
@@ -0,0 +1,17 @@
+package xxx;
+
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/**
+ * Fake shadow for testing {@link org.robolectric.errorprone.bugpatterns.DeprecatedMethodsCheck}.
+ */
+@Implements(ConnectivityManager.class)
+public class XShadowConnectivityManager {
+ @Implementation
+ public NetworkInfo getActiveNetworkInfo() {
+ return null;
+ }
+}
diff --git a/errorprone/src/test/java/xxx/XShadowDialog.java b/errorprone/src/test/java/xxx/XShadowDialog.java
new file mode 100644
index 000000000..c9ffdbfc3
--- /dev/null
+++ b/errorprone/src/test/java/xxx/XShadowDialog.java
@@ -0,0 +1,14 @@
+package xxx;
+
+import android.app.Dialog;
+import org.robolectric.annotation.Implements;
+
+/**
+ * Fake shadow for testing {@link org.robolectric.errorprone.bugpatterns.DeprecatedMethodsCheck}.
+ */
+@Implements(Dialog.class)
+public class XShadowDialog {
+ public static Dialog getLatestDialog() {
+ return null;
+ }
+}
diff --git a/errorprone/src/test/java/xxx/XShadowLooper.java b/errorprone/src/test/java/xxx/XShadowLooper.java
new file mode 100644
index 000000000..619a0831f
--- /dev/null
+++ b/errorprone/src/test/java/xxx/XShadowLooper.java
@@ -0,0 +1,23 @@
+package xxx;
+
+import android.os.Looper;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/**
+ * Fake shadow for testing {@link org.robolectric.errorprone.bugpatterns.DeprecatedMethodsCheck}.
+ */
+@Implements(Looper.class)
+public class XShadowLooper {
+ @Implementation
+ public static Looper getMainLooper() {
+ return null;
+ }
+
+ public String getSchedule() {
+ return null;
+ }
+
+ public void runToEndOfTasks() {
+ }
+}
diff --git a/errorprone/src/test/java/xxx/XShadowNetworkInfo.java b/errorprone/src/test/java/xxx/XShadowNetworkInfo.java
new file mode 100644
index 000000000..17e15ca31
--- /dev/null
+++ b/errorprone/src/test/java/xxx/XShadowNetworkInfo.java
@@ -0,0 +1,13 @@
+package xxx;
+
+import android.net.ConnectivityManager;
+import org.robolectric.annotation.Implements;
+
+/**
+ * Fake shadow for testing {@link org.robolectric.errorprone.bugpatterns.DeprecatedMethodsCheck}.
+ */
+@Implements(ConnectivityManager.class)
+public class XShadowNetworkInfo {
+ public void setConnectionType(int connectionType) {
+ }
+}
diff --git a/errorprone/src/test/java/xxx/XShadowPopupMenu.java b/errorprone/src/test/java/xxx/XShadowPopupMenu.java
new file mode 100644
index 000000000..56764765c
--- /dev/null
+++ b/errorprone/src/test/java/xxx/XShadowPopupMenu.java
@@ -0,0 +1,14 @@
+package xxx;
+
+import android.widget.PopupMenu;
+import org.robolectric.annotation.Implements;
+
+/**
+ * Fake shadow for testing {@link org.robolectric.errorprone.bugpatterns.DeprecatedMethodsCheck}.
+ */
+@Implements(PopupMenu.class)
+public class XShadowPopupMenu {
+ public static PopupMenu getLatestPopupMenu() {
+ return null;
+ }
+}
diff --git a/errorprone/src/test/java/xxx/XShadows.java b/errorprone/src/test/java/xxx/XShadows.java
index dbccd65ed..45e1546cd 100644
--- a/errorprone/src/test/java/xxx/XShadows.java
+++ b/errorprone/src/test/java/xxx/XShadows.java
@@ -1,24 +1,42 @@
package xxx;
+import android.app.AlertDialog;
import android.app.Application;
+import android.app.Dialog;
import android.graphics.drawable.Drawable;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Looper;
import android.view.ViewGroup;
import android.widget.LinearLayout;
+import android.widget.PopupMenu;
/**
* Fake {@link org.robolectric.internal.ShadowProvider} for testing
* {@link org.robolectric.errorprone.bugpatterns.ShadowUsageCheck}.
*/
public class XShadows implements org.robolectric.internal.ShadowProvider {
+ public static XShadowAlertDialog shadowOf(AlertDialog actual) {
+ return null;
+ }
+
public static XShadowApplication shadowOf(Application actual) {
return null;
}
+ public static XShadowConnectivityManager shadowOf(ConnectivityManager actual) {
+ return null;
+ }
+
+ public static XShadowDialog shadowOf(Dialog actual) {
+ return null;
+ }
+
public static XShadowDrawable shadowOf(Drawable actual) {
return null;
}
- public static XShadowViewGroup shadowOf(ViewGroup actual) {
+ public static XShadowLooper shadowOf(Looper actual) {
return null;
}
@@ -26,6 +44,18 @@ public class XShadows implements org.robolectric.internal.ShadowProvider {
return null;
}
+ public static XShadowNetworkInfo shadowOf(NetworkInfo actual) {
+ return null;
+ }
+
+ public static XShadowPopupMenu shadowOf(PopupMenu actual) {
+ return null;
+ }
+
+ public static XShadowViewGroup shadowOf(ViewGroup actual) {
+ return null;
+ }
+
@Override
public void reset() {}
diff --git a/gradle.properties b/gradle.properties
index 8204ee9bf..1f181dac2 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,3 +1,8 @@
-thisVersion=4.0-alpha-4-SNAPSHOT
+thisVersion=4.1-SNAPSHOT
apiCompatVersion=3.8
+
+errorproneVersion=2.3.1
+errorproneJavacVersion=9+181-r4173-1
+
+android.enableUnitTestBinaryResources=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 7a3265ee9..29953ea14 100644
--- a/gradle/wrapper/gradle-wrapper.jar
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/integration_tests/androidx_test/build.gradle b/integration_tests/androidx_test/build.gradle
index 4c9fb7687..da275644c 100644
--- a/integration_tests/androidx_test/build.gradle
+++ b/integration_tests/androidx_test/build.gradle
@@ -1,11 +1,17 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
apply plugin: 'com.android.library'
android {
- compileSdkVersion 27
+ compileSdkVersion 28
+
+ defaultConfig {
+ minSdkVersion 16
+ targetSdkVersion 28
+ }
+
+ compileOptions {
+ sourceCompatibility = '1.8'
+ targetCompatibility = '1.8'
+ }
android {
testOptions {
@@ -20,13 +26,19 @@ android {
dependencies {
implementation project(":robolectric")
implementation "junit:junit:4.12"
- implementation("androidx.test:runner:1.1.0-alpha4")
+ implementation("androidx.test:runner:1.1.0")
+ implementation("androidx.appcompat:appcompat:1.0.0")
// Testing dependencies
- testImplementation("androidx.test:runner:1.1.0-alpha4")
- testImplementation("androidx.test:rules:1.1.0-alpha4")
- testImplementation("androidx.test.espresso:espresso-intents:3.1.0-alpha4")
- testImplementation("androidx.test.espresso:espresso-core:3.1.0-alpha4")
- testImplementation("androidx.test.ext:truth:1.0.0-alpha4")
- testImplementation("com.google.truth:truth:0.36")
+ testImplementation("androidx.test:runner:1.1.0")
+ testImplementation("androidx.test:rules:1.1.0")
+ testImplementation("androidx.test.espresso:espresso-intents:3.1.0")
+ testImplementation("androidx.test.espresso:espresso-core:3.1.0")
+ testImplementation("androidx.test.ext:truth:1.0.0")
+ testImplementation("androidx.test:core:1.0.0")
+ // TODO: this should be a transitive dependency of core...
+ testImplementation("androidx.lifecycle:lifecycle-common:2.0.0")
+ testImplementation("androidx.test.ext:junit:1.0.0")
+ testImplementation("com.google.truth:truth:0.42")
+
}
diff --git a/integration_tests/androidx_test/src/test/java/org/robolectric/integration_tests/axt/ActivityScenarioTest.java b/integration_tests/androidx_test/src/test/java/org/robolectric/integration_tests/axt/ActivityScenarioTest.java
new file mode 100644
index 000000000..859fe774f
--- /dev/null
+++ b/integration_tests/androidx_test/src/test/java/org/robolectric/integration_tests/axt/ActivityScenarioTest.java
@@ -0,0 +1,120 @@
+package org.robolectric.integration_tests.axt;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Activity;
+import androidx.lifecycle.Lifecycle.State;
+import android.os.Bundle;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.R;
+import androidx.test.core.app.ActivityScenario;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Integration tests for {@link ActivityScenario} that verify it behaves consistently on device and
+ * Robolectric.
+ */
+@RunWith(AndroidJUnit4.class)
+public class ActivityScenarioTest {
+
+ private static final List<String> callbacks = new ArrayList<>();
+
+ public static class TranscriptActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ callbacks.add("onCreate");
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ callbacks.add("onStart");
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ callbacks.add("onResume");
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ callbacks.add("onPause");
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ callbacks.add("onStop");
+ }
+
+ @Override
+ public void onRestart() {
+ super.onRestart();
+ callbacks.add("onRestart");
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ callbacks.add("onDestroy");
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ callbacks.add("onWindowFocusChanged " + hasFocus);
+ }
+ }
+
+ public static class LifecycleOwnerActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ setTheme(R.style.Theme_AppCompat);
+ }
+ }
+
+ @Before
+ public void setUp() {
+ callbacks.clear();
+ }
+
+ @Test
+ public void launch_callbackSequence() {
+ ActivityScenario<TranscriptActivity> activityScenario =
+ ActivityScenario.launch(TranscriptActivity.class);
+ assertThat(activityScenario).isNotNull();
+ assertThat(callbacks)
+ .containsExactly("onCreate", "onStart", "onResume", "onWindowFocusChanged true");
+ }
+
+ @Test
+ public void launch_lifecycleOwnerActivity() {
+ ActivityScenario<LifecycleOwnerActivity> activityScenario =
+ ActivityScenario.launch(LifecycleOwnerActivity.class);
+ assertThat(activityScenario).isNotNull();
+ activityScenario.onActivity(
+ activity -> {
+ assertThat(activity.getLifecycle().getCurrentState()).isEqualTo(State.RESUMED);
+ });
+ activityScenario.moveToState(State.STARTED);
+ activityScenario.onActivity(
+ activity -> {
+ assertThat(activity.getLifecycle().getCurrentState()).isEqualTo(State.STARTED);
+ });
+ activityScenario.moveToState(State.CREATED);
+ activityScenario.onActivity(
+ activity -> {
+ assertThat(activity.getLifecycle().getCurrentState()).isEqualTo(State.CREATED);
+ });
+ }
+}
diff --git a/integration_tests/ctesque/AndroidManifest.xml b/integration_tests/ctesque/AndroidManifest.xml
index 848850f24..f6cfadcd5 100644
--- a/integration_tests/ctesque/AndroidManifest.xml
+++ b/integration_tests/ctesque/AndroidManifest.xml
@@ -4,7 +4,9 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.robolectric.integration_tests.ctesque">
- <uses-sdk android:targetSdkVersion="27"/>
+ <uses-sdk
+ android:minSdkVersion="16"
+ android:targetSdkVersion="27" />
<!-- For SettingsTest -->
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
diff --git a/integration_tests/ctesque/build.gradle b/integration_tests/ctesque/build.gradle
index c7662aaf0..5f8fd96ba 100644
--- a/integration_tests/ctesque/build.gradle
+++ b/integration_tests/ctesque/build.gradle
@@ -1,11 +1,11 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
apply plugin: 'com.android.library'
android {
- compileSdkVersion 27
+ compileSdkVersion 28
+ defaultConfig {
+ minSdkVersion 16
+ targetSdkVersion 28
+ }
lintOptions {
abortOnError false
@@ -30,21 +30,20 @@ dependencies {
implementation project(path: ':testapp', configuration: 'default')
implementation project(path: ':shadowapi', configuration: 'default')
- // Testing dependencies
testImplementation project(":robolectric")
testImplementation "junit:junit:4.12"
- testImplementation("androidx.test:monitor:1.1.0-alpha4")
- testImplementation("androidx.test:runner:1.1.0-alpha4")
- testImplementation("androidx.test:rules:1.1.0-alpha4")
- testImplementation("androidx.test.ext:truth:1.0.0-alpha4")
- testImplementation("androidx.test:core:1.0.0-alpha4")
- testImplementation "com.google.truth:truth:0.36"
- testImplementation "com.google.guava:guava:20.0"
+ testImplementation("androidx.test:monitor:1.1.0")
+ testImplementation("androidx.test:runner:1.1.0")
+ testImplementation("androidx.test:rules:1.1.0")
+ testImplementation("androidx.test.ext:truth:1.0.0")
+ testImplementation("androidx.test:core:1.0.0")
+ testImplementation("com.google.truth:truth:0.42")
+ testImplementation("com.google.guava:guava:20.0")
// Testing dependencies
- androidTestImplementation("androidx.test:monitor:1.1.0-alpha4")
- androidTestImplementation("androidx.test:runner:1.1.0-alpha4")
- androidTestImplementation("androidx.test:rules:1.1.0-alpha4")
- androidTestImplementation "com.google.truth:truth:0.36"
- androidTestImplementation "com.google.guava:guava:20.0"
+ androidTestImplementation("androidx.test:monitor:1.1.0")
+ androidTestImplementation("androidx.test:runner:1.1.0")
+ androidTestImplementation("androidx.test:rules:1.1.0")
+ androidTestImplementation("com.google.truth:truth:0.42")
+ androidTestImplementation("com.google.guava:guava:20.0")
}
diff --git a/integration_tests/ctesque/src/test/java/android/content/pm/PackageManagerTest.java b/integration_tests/ctesque/src/test/java/android/content/pm/PackageManagerTest.java
new file mode 100644
index 000000000..1ff59571c
--- /dev/null
+++ b/integration_tests/ctesque/src/test/java/android/content/pm/PackageManagerTest.java
@@ -0,0 +1,49 @@
+package android.content.pm;
+
+import static android.os.Build.VERSION_CODES.O;
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ComponentName;
+import android.content.Context;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+/**
+ * Compatibility test for {@link PackageManager}
+ */
+@DoNotInstrument
+@RunWith(AndroidJUnit4.class)
+public final class PackageManagerTest {
+
+ private Context context;
+
+ @Before
+ public void setup() throws Exception {
+ context = InstrumentationRegistry.getTargetContext();
+ }
+
+ @Test
+ @Config(minSdk = O)
+ @SdkSuppress(minSdkVersion = O)
+ public void isInstantApp_shouldNotBlowup() {
+ assertThat(context.getPackageManager().isInstantApp()).isFalse();
+ }
+
+ @Test
+ public void whenComponentDisabled_itIsReportedAsSuch() throws Exception {
+ PackageManager pm = context.getPackageManager();
+ ComponentName disabledActivityName =
+ new ComponentName(context, "org.robolectric.DisabledTestActivity");
+
+ ActivityInfo info =
+ pm.getActivityInfo(disabledActivityName, PackageManager.GET_DISABLED_COMPONENTS);
+ assertThat(info).isNotNull();
+ assertThat(info.enabled).isFalse();
+ }
+}
diff --git a/integration_tests/ctesque/src/test/java/android/content/res/AssetManagerTest.java b/integration_tests/ctesque/src/test/java/android/content/res/AssetManagerTest.java
index b65dcb92e..9ae361e1a 100644
--- a/integration_tests/ctesque/src/test/java/android/content/res/AssetManagerTest.java
+++ b/integration_tests/ctesque/src/test/java/android/content/res/AssetManagerTest.java
@@ -13,6 +13,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -64,7 +65,7 @@ public class AssetManagerTest {
assertThat(contents).isEqualTo("assetsHome!");
}
- @Test
+ @Test @Ignore("TODO(xian): re-enable; see https://github.com/robolectric/robolectric/issues/4091")
public void openFd_shouldProvideFileDescriptorForAsset() throws Exception {
AssetFileDescriptor assetFileDescriptor = assetManager.openFd("assetsHome.txt");
assertThat(CharStreams.toString(new InputStreamReader(assetFileDescriptor.createInputStream(), UTF_8)))
@@ -88,8 +89,8 @@ public class AssetManagerTest {
new AssetFileDescriptor(parcelFileDescriptor, 0, "hi".getBytes().length);
assertThat(
- CharStreams.toString(
- new InputStreamReader(assetFileDescriptor.createInputStream(), UTF_8)))
+ CharStreams.toString(
+ new InputStreamReader(assetFileDescriptor.createInputStream(), UTF_8)))
.isEqualTo("hi");
assertThat(assetFileDescriptor.getLength()).isEqualTo(2);
assetFileDescriptor.close();
diff --git a/integration_tests/ctesque/src/test/java/android/content/res/ResourcesTest.java b/integration_tests/ctesque/src/test/java/android/content/res/ResourcesTest.java
index d0fbafe7f..67a837418 100644
--- a/integration_tests/ctesque/src/test/java/android/content/res/ResourcesTest.java
+++ b/integration_tests/ctesque/src/test/java/android/content/res/ResourcesTest.java
@@ -3,6 +3,7 @@ package android.content.res;
import static android.os.Build.VERSION_CODES.KITKAT;
import static android.os.Build.VERSION_CODES.KITKAT_WATCH;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
+import static android.os.Build.VERSION_CODES.O;
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
import static android.util.TypedValue.COMPLEX_UNIT_IN;
import static android.util.TypedValue.COMPLEX_UNIT_MM;
@@ -27,6 +28,7 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
+import android.graphics.Typeface;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
@@ -42,6 +44,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.google.common.collect.Range;
import java.io.File;
import java.io.InputStream;
+import java.lang.reflect.Method;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -284,7 +287,7 @@ public class ResourcesTest {
}
@Test
- public void getDimensionPixelOffset() throws Exception {
+ public void getDimensionPixelOffset() {
assertThat(resources.getDimensionPixelOffset(R.dimen.test_dip_dimen))
.isEqualTo(convertDimension(COMPLEX_UNIT_DIP, 20));
assertThat(resources.getDimensionPixelOffset(R.dimen.test_dp_dimen))
@@ -306,31 +309,40 @@ public class ResourcesTest {
}
@Test
- public void getDimension_withReference() throws Exception {
+ public void getDimension_withReference() {
assertThat(resources.getBoolean(R.bool.reference_to_true)).isEqualTo(true);
}
@Test(expected = Resources.NotFoundException.class)
- public void getStringArray_shouldThrowExceptionIfNotFound() throws Exception {
+ public void getStringArray_shouldThrowExceptionIfNotFound() {
resources.getStringArray(-1);
}
@Test(expected = Resources.NotFoundException.class)
- public void getIntegerArray_shouldThrowExceptionIfNotFound() throws Exception {
+ public void getIntegerArray_shouldThrowExceptionIfNotFound() {
resources.getIntArray(-1);
}
@Test
- @Ignore("todo: incorrect behavior on robolectric vs framework?")
- public void getQuantityString() throws Exception {
- assertThat(resources.getQuantityString(R.plurals.beer, 0)).isEqualTo("Howdy");
- assertThat(resources.getQuantityString(R.plurals.beer, 1)).isEqualTo("One beer");
- assertThat(resources.getQuantityString(R.plurals.beer, 2)).isEqualTo("Two beers");
- assertThat(resources.getQuantityString(R.plurals.beer, 3)).isEqualTo("%d beers, yay!");
+ public void getQuantityString() {
+ assertThat(resources.getQuantityString(R.plurals.beer, 1)).isEqualTo("a beer");
+ assertThat(resources.getQuantityString(R.plurals.beer, 2)).isEqualTo("some beers");
+ assertThat(resources.getQuantityString(R.plurals.beer, 3)).isEqualTo("some beers");
}
@Test
- public void getFraction() throws Exception {
+ public void getQuantityText() {
+ // Feature not supported in legacy (raw) resource mode.
+ if (isRobolectricLegacyMode()) {
+ return;
+ }
+ assertThat(resources.getQuantityText(R.plurals.beer, 1)).isEqualTo("a beer");
+ assertThat(resources.getQuantityText(R.plurals.beer, 2)).isEqualTo("some beers");
+ assertThat(resources.getQuantityText(R.plurals.beer, 3)).isEqualTo("some beers");
+ }
+
+ @Test
+ public void getFraction() {
final int myself = 300;
final int myParent = 600;
assertThat(resources.getFraction(R.fraction.half, myself, myParent)).isEqualTo(150f);
@@ -361,7 +373,7 @@ public class ResourcesTest {
}
@Test(expected = Resources.NotFoundException.class)
- public void testGetDrawableNullRClass() throws Exception {
+ public void testGetDrawableNullRClass() {
assertThat(resources.getDrawable(-12345)).isInstanceOf(BitmapDrawable.class);
}
@@ -1037,6 +1049,18 @@ public class ResourcesTest {
.isEqualTo("TextAppearance.Small");
}
+ @Test
+ @SdkSuppress(minSdkVersion = O)
+ @Config(minSdk = O)
+ public void getFont() {
+ // Feature not supported in legacy (raw) resource mode.
+ if (isRobolectricLegacyMode()) {
+ return;
+ }
+ Typeface typeface = resources.getFont(R.font.vt323_regular);
+ assertThat(typeface).isNotNull();
+ }
+
///////////////////
private static String findRootTag(XmlResourceParser parser) throws Exception {
@@ -1052,4 +1076,16 @@ public class ResourcesTest {
super(res.getAssets(), res.getDisplayMetrics(), res.getConfiguration());
}
}
+
+ private static boolean isRobolectricLegacyMode() {
+ try {
+ Class runtimeEnvironmentClass = Class.forName("org.robolectric.RuntimeEnvironment");
+ Method useLegacyResourcesMethod =
+ runtimeEnvironmentClass.getDeclaredMethod("useLegacyResources");
+ boolean result = (Boolean) useLegacyResourcesMethod.invoke(null);
+ return result;
+ } catch (Exception e) {
+ return false;
+ }
+ }
}
diff --git a/integration_tests/ctesque/src/test/java/android/graphics/BitmapTest.java b/integration_tests/ctesque/src/test/java/android/graphics/BitmapTest.java
new file mode 100644
index 000000000..4c88615cb
--- /dev/null
+++ b/integration_tests/ctesque/src/test/java/android/graphics/BitmapTest.java
@@ -0,0 +1,46 @@
+package android.graphics;
+
+import static android.os.Build.VERSION_CODES.P;
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.filters.SdkSuppress;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+/** Compatibility test for {@link Bitmap} */
+@DoNotInstrument
+@RunWith(AndroidJUnit4.class)
+public class BitmapTest {
+
+ @Config(minSdk = P)
+ @SdkSuppress(minSdkVersion = P)
+ @Test public void createBitmap() {
+
+ Picture picture = new Picture();
+ Canvas canvas = picture.beginRecording(200, 100);
+
+ Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+ p.setColor(0x88FF0000);
+ canvas.drawCircle(50, 50, 40, p);
+
+ p.setColor(Color.GREEN);
+ p.setTextSize(30);
+ canvas.drawText("Pictures", 60, 60, p);
+ picture.endRecording();
+
+ Bitmap bitmap = Bitmap.createBitmap(picture);
+ assertThat(bitmap.isMutable()).isFalse();
+ }
+
+ @Test
+ public void testEraseColor() {
+ Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+ bitmap.eraseColor(0xffff0000);
+ assertThat(bitmap.getPixel(10, 10)).isEqualTo(0xffff0000);
+ assertThat(bitmap.getPixel(50, 50)).isEqualTo(0xffff0000);
+ }
+}
diff --git a/integration_tests/ctesque/src/test/java/android/graphics/MatrixTest.java b/integration_tests/ctesque/src/test/java/android/graphics/MatrixTest.java
new file mode 100644
index 000000000..d4ec68266
--- /dev/null
+++ b/integration_tests/ctesque/src/test/java/android/graphics/MatrixTest.java
@@ -0,0 +1,125 @@
+package android.graphics;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.graphics.Matrix.ScaleToFit;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+/** Compatibility test for {@link Matrix} */
+@DoNotInstrument
+@RunWith(AndroidJUnit4.class)
+public final class MatrixTest {
+
+ @Test
+ public void mapRadius() throws Exception {
+ Matrix matrix = new Matrix();
+
+ assertThat(matrix.mapRadius(100f)).isEqualTo(100f);
+ assertThat(matrix.mapRadius(Float.MAX_VALUE)).isEqualTo(Float.POSITIVE_INFINITY);
+ assertThat(matrix.mapRadius(Float.MIN_VALUE)).isEqualTo(0f);
+
+ matrix.postScale(2.0f, 2.0f);
+ assertThat(matrix.mapRadius(1.0f)).isWithin(0.01f).of(2.0f);
+ }
+
+ @Test
+ public void mapPoints() {
+ float[] value = new float[9];
+ value[0] = 100f;
+ new Matrix().mapPoints(value);
+ assertThat(value[0]).isEqualTo(100f);
+ }
+
+ @Test(expected = Exception.class)
+ public void mapPointsNull() {
+ new Matrix().mapPoints(null);
+ }
+
+ @Test
+ public void mapPoints2() {
+ float[] dst = new float[9];
+ dst[0] = 100f;
+ float[] src = new float[9];
+ src[0] = 200f;
+ new Matrix().mapPoints(dst, src);
+ assertThat(dst[0]).isEqualTo(200f);
+ }
+
+ @Test(expected = Exception.class)
+ public void mapPointsArraysMismatch() {
+ new Matrix().mapPoints(new float[8], new float[9]);
+ }
+
+ @Test
+ public void mapPointsWithIndices() {
+ float[] dst = new float[9];
+ dst[0] = 100f;
+ float[] src = new float[9];
+ src[0] = 200f;
+ new Matrix().mapPoints(dst, 0, src, 0, 9 >> 1);
+ assertThat(dst[0]).isEqualTo(200f);
+ }
+
+ @Test(expected = Exception.class)
+ public void mapPointsWithIndicesNull() {
+ new Matrix().mapPoints(null, 0, new float[9], 0, 1);
+ }
+
+ @Test
+ public void setRectToRect() {
+ RectF r1 = new RectF();
+ r1.set(1f, 2f, 3f, 3f);
+ RectF r2 = new RectF();
+ r1.set(10f, 20f, 30f, 30f);
+ Matrix matrix = new Matrix();
+ float[] result = new float[9];
+
+ assertThat(matrix.setRectToRect(r1, r2, ScaleToFit.CENTER)).isTrue();
+ matrix.getValues(result);
+ assertThat(result)
+ .isEqualTo(new float[] {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f});
+
+ matrix.setRectToRect(r1, r2, ScaleToFit.END);
+ matrix.getValues(result);
+ assertThat(result)
+ .isEqualTo(new float[] {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f});
+
+ matrix.setRectToRect(r1, r2, ScaleToFit.FILL);
+ matrix.getValues(result);
+ assertThat(result)
+ .isEqualTo(new float[] {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f});
+
+ matrix.setRectToRect(r1, r2, ScaleToFit.START);
+ matrix.getValues(result);
+ assertThat(result)
+ .isEqualTo(new float[] {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f});
+
+ assertThat(matrix.setRectToRect(r2, r1, ScaleToFit.CENTER)).isFalse();
+ matrix.getValues(result);
+ assertThat(result)
+ .isEqualTo(new float[] {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f});
+
+ assertThat(matrix.setRectToRect(r2, r1, ScaleToFit.FILL)).isFalse();
+ matrix.getValues(result);
+ assertThat(result)
+ .isEqualTo(new float[] {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f});
+
+ assertThat(matrix.setRectToRect(r2, r1, ScaleToFit.START)).isFalse();
+ matrix.getValues(result);
+ assertThat(result)
+ .isEqualTo(new float[] {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f});
+
+ assertThat(matrix.setRectToRect(r2, r1, ScaleToFit.END)).isFalse();
+ matrix.getValues(result);
+ assertThat(result)
+ .isEqualTo(new float[] {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f});
+ }
+
+ @Test(expected = Exception.class)
+ public void testSetRectToRectNull() {
+ new Matrix().setRectToRect(null, null, ScaleToFit.CENTER);
+ }
+}
diff --git a/integration_tests/ctesque/src/test/java/android/graphics/PathTest.java b/integration_tests/ctesque/src/test/java/android/graphics/PathTest.java
new file mode 100644
index 000000000..a362df409
--- /dev/null
+++ b/integration_tests/ctesque/src/test/java/android/graphics/PathTest.java
@@ -0,0 +1,117 @@
+package android.graphics;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+/** Compatibility test for {@link Path} */
+@DoNotInstrument
+@RunWith(AndroidJUnit4.class)
+public class PathTest {
+
+ // Test constants
+ private static final float LEFT = 10.0f;
+ private static final float RIGHT = 50.0f;
+ private static final float TOP = 10.0f;
+ private static final float BOTTOM = 50.0f;
+ private static final float XCOORD = 40.0f;
+ private static final float YCOORD = 40.0f;
+
+ @Test
+ public void moveTo() {
+ Path path = new Path();
+ assertThat(path.isEmpty()).isTrue();
+
+ path.moveTo(0, 0);
+ assertThat(path.isEmpty()).isFalse();
+ }
+
+ @Test
+ public void lineTo() {
+ Path path = new Path();
+ assertThat(path.isEmpty()).isTrue();
+ path.lineTo(XCOORD, YCOORD);
+ assertThat(path.isEmpty()).isFalse();
+ }
+
+ @Test
+ public void quadTo() {
+ Path path = new Path();
+ assertThat(path.isEmpty()).isTrue();
+ path.quadTo(20.0f, 20.0f, 40.0f, 40.0f);
+ assertThat(path.isEmpty()).isFalse();
+ }
+
+ @Test
+ public void addRect1() {
+ Path path = new Path();
+ assertThat(path.isEmpty()).isTrue();
+ RectF rect = new RectF(LEFT, TOP, RIGHT, BOTTOM);
+ path.addRect(rect, Path.Direction.CW);
+ assertThat(path.isEmpty()).isFalse();
+ }
+
+ @Test
+ public void addRect2() {
+ Path path = new Path();
+ assertThat(path.isEmpty()).isTrue();
+ path.addRect(LEFT, TOP, RIGHT, BOTTOM, Path.Direction.CW);
+ assertThat(path.isEmpty()).isFalse();
+ }
+
+ @Test
+ public void getFillType() {
+ Path path = new Path();
+ path.setFillType(Path.FillType.EVEN_ODD);
+ assertThat(path.getFillType()).isEqualTo(Path.FillType.EVEN_ODD);
+ }
+
+ @Test
+ public void transform() {
+ Path path = new Path();
+ assertThat(path.isEmpty()).isTrue();
+
+ Path dst = new Path();
+ path.addRect(new RectF(LEFT, TOP, RIGHT, BOTTOM), Path.Direction.CW);
+ path.transform(new Matrix(), dst);
+
+ assertThat(dst.isEmpty()).isFalse();
+ }
+
+ @Test
+ public void testAddCircle() {
+ // new the Path instance
+ Path path = new Path();
+ assertThat(path.isEmpty()).isTrue();
+ path.addCircle(XCOORD, YCOORD, 10.0f, Path.Direction.CW);
+ assertThat(path.isEmpty()).isFalse();
+ }
+
+ @Test
+ public void arcTo1() {
+ Path path = new Path();
+ assertThat(path.isEmpty()).isTrue();
+ RectF oval = new RectF(LEFT, TOP, RIGHT, BOTTOM);
+ path.arcTo(oval, 0.0f, 30.0f, true);
+ assertThat(path.isEmpty()).isFalse();
+ }
+
+ @Test
+ public void arcTo2() {
+ Path path = new Path();
+ assertThat(path.isEmpty()).isTrue();
+ RectF oval = new RectF(LEFT, TOP, RIGHT, BOTTOM);
+ path.arcTo(oval, 0.0f, 30.0f);
+ assertThat(path.isEmpty()).isFalse();
+ }
+
+ @Test
+ public void close() {
+ Path path = new Path();
+ assertThat(path.isEmpty()).isTrue();
+ path.close();
+ }
+}
diff --git a/integration_tests/ctesque/src/test/java/android/view/MotionEventTest.java b/integration_tests/ctesque/src/test/java/android/view/MotionEventTest.java
index ca4f62ed8..dcd712c03 100644
--- a/integration_tests/ctesque/src/test/java/android/view/MotionEventTest.java
+++ b/integration_tests/ctesque/src/test/java/android/view/MotionEventTest.java
@@ -1,7 +1,5 @@
package android.view;
-import static androidx.test.core.view.PointerCoordsBuilder.buildPointerCoords;
-import static androidx.test.core.view.PointerPropertiesBuilder.buildPointerProperties;
import static androidx.test.ext.truth.view.MotionEventSubject.assertThat;
import static androidx.test.ext.truth.view.PointerCoordsSubject.assertThat;
import static androidx.test.ext.truth.view.PointerPropertiesSubject.assertThat;
@@ -16,6 +14,8 @@ import android.os.Parcelable;
import android.os.SystemClock;
import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties;
+import androidx.test.core.view.PointerCoordsBuilder;
+import androidx.test.core.view.PointerPropertiesBuilder;
import androidx.test.runner.AndroidJUnit4;
import com.google.common.truth.FailureMetadata;
import com.google.common.truth.Subject;
@@ -168,14 +168,14 @@ public class MotionEventTest {
@Test
public void testObtainFromPropertyArrays() {
PointerCoords coords0 =
- buildPointerCoords()
+ PointerCoordsBuilder.newBuilder()
.setCoords(X_3F, Y_4F)
.setPressure(PRESSURE_1F)
.setSize(SIZE_1F)
.setTool(1.2f, 1.4f)
.build();
PointerCoords coords1 =
- buildPointerCoords()
+ PointerCoordsBuilder.newBuilder()
.setCoords(X_3F + 1.0f, Y_4F - 2.0f)
.setPressure(PRESSURE_1F + 0.2f)
.setSize(SIZE_1F + 0.5f)
@@ -183,9 +183,15 @@ public class MotionEventTest {
.build();
PointerProperties properties0 =
- buildPointerProperties().setId(0).setToolType(MotionEvent.TOOL_TYPE_FINGER).build();
+ PointerPropertiesBuilder.newBuilder()
+ .setId(0)
+ .setToolType(MotionEvent.TOOL_TYPE_FINGER)
+ .build();
PointerProperties properties1 =
- buildPointerProperties().setId(1).setToolType(MotionEvent.TOOL_TYPE_FINGER).build();
+ PointerPropertiesBuilder.newBuilder()
+ .setId(1)
+ .setToolType(MotionEvent.TOOL_TYPE_FINGER)
+ .build();
motionEventDynamic =
MotionEvent.obtain(
@@ -389,14 +395,14 @@ public class MotionEventTest {
@Test
public void testGetCurrentDataWithTwoPointers() {
PointerCoords coords0 =
- buildPointerCoords()
+ PointerCoordsBuilder.newBuilder()
.setCoords(10.0f, 20.0f)
.setPressure(1.2f)
.setSize(2.0f)
.setTool(1.2f, 1.4f)
.build();
PointerCoords coords1 =
- buildPointerCoords()
+ PointerCoordsBuilder.newBuilder()
.setCoords(30.0f, 40.0f)
.setPressure(1.4f)
.setSize(3.0f)
@@ -404,9 +410,15 @@ public class MotionEventTest {
.build();
PointerProperties properties0 =
- buildPointerProperties().setId(0).setToolType(MotionEvent.TOOL_TYPE_FINGER).build();
+ PointerPropertiesBuilder.newBuilder()
+ .setId(0)
+ .setToolType(MotionEvent.TOOL_TYPE_FINGER)
+ .build();
PointerProperties properties1 =
- buildPointerProperties().setId(1).setToolType(MotionEvent.TOOL_TYPE_FINGER).build();
+ PointerPropertiesBuilder.newBuilder()
+ .setId(1)
+ .setToolType(MotionEvent.TOOL_TYPE_FINGER)
+ .build();
motionEventDynamic =
MotionEvent.obtain(
@@ -445,7 +457,7 @@ public class MotionEventTest {
public void testGetHistoricalDataWithTwoPointers() {
// PHASE 1 - construct the initial data for the event
PointerCoords coordsInitial0 =
- buildPointerCoords()
+ PointerCoordsBuilder.newBuilder()
.setCoords(10.0f, 20.0f)
.setPressure(1.2f)
.setSize(2.0f)
@@ -454,7 +466,7 @@ public class MotionEventTest {
.setOrientation(2.0f)
.build();
PointerCoords coordsInitial1 =
- buildPointerCoords()
+ PointerCoordsBuilder.newBuilder()
.setCoords(30.0f, 40.0f)
.setPressure(1.4f)
.setSize(3.0f)
@@ -464,9 +476,15 @@ public class MotionEventTest {
.build();
PointerProperties properties0 =
- buildPointerProperties().setId(0).setToolType(MotionEvent.TOOL_TYPE_FINGER).build();
+ PointerPropertiesBuilder.newBuilder()
+ .setId(0)
+ .setToolType(MotionEvent.TOOL_TYPE_FINGER)
+ .build();
PointerProperties properties1 =
- buildPointerProperties().setId(1).setToolType(MotionEvent.TOOL_TYPE_FINGER).build();
+ PointerPropertiesBuilder.newBuilder()
+ .setId(1)
+ .setToolType(MotionEvent.TOOL_TYPE_FINGER)
+ .build();
motionEventDynamic =
MotionEvent.obtain(
@@ -501,7 +519,7 @@ public class MotionEventTest {
// PHASE 2 - add a new batch of data to our event
PointerCoords coordsNext0 =
- buildPointerCoords()
+ PointerCoordsBuilder.newBuilder()
.setCoords(15.0f, 25.0f)
.setPressure(1.6f)
.setSize(2.2f)
@@ -510,7 +528,7 @@ public class MotionEventTest {
.setOrientation(2.2f)
.build();
PointerCoords coordsNext1 =
- buildPointerCoords()
+ PointerCoordsBuilder.newBuilder()
.setCoords(35.0f, 45.0f)
.setPressure(1.8f)
.setSize(3.2f)
diff --git a/integration_tests/dependency-on-stubs/build.gradle b/integration_tests/dependency-on-stubs/build.gradle
index dd69b4ca7..8bce7d21e 100644
--- a/integration_tests/dependency-on-stubs/build.gradle
+++ b/integration_tests/dependency-on-stubs/build.gradle
@@ -1,17 +1,12 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
apply plugin: RoboJavaModulePlugin
// test with a project that depends on the stubs jar, not org.robolectric:android-all
dependencies {
- compile project(":robolectric")
- compile "junit:junit:4.12"
- testCompile "com.google.android:android-stubs:28"
+ api project(":robolectric")
+ api "junit:junit:4.12"
+ testImplementation "com.google.android:android-stubs:28"
- // Testing dependencies
- testCompile "com.google.truth:truth:0.39"
- testCompile "org.mockito:mockito-core:2.5.4"
+ testImplementation "com.google.truth:truth:0.42"
+ testImplementation "org.mockito:mockito-core:2.5.4"
}
diff --git a/integration_tests/libphonenumber/build.gradle b/integration_tests/libphonenumber/build.gradle
index b26c1981a..b5e29ff34 100644
--- a/integration_tests/libphonenumber/build.gradle
+++ b/integration_tests/libphonenumber/build.gradle
@@ -1,16 +1,11 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
apply plugin: RoboJavaModulePlugin
dependencies {
- compile project(":robolectric")
- compile "junit:junit:4.12"
+ api project(":robolectric")
+ api "junit:junit:4.12"
compileOnly AndroidSdk.MAX_SDK.coordinates
- // Testing dependencies
testRuntime AndroidSdk.MAX_SDK.coordinates
- testImplementation "com.google.truth:truth:0.39"
- testCompile 'com.googlecode.libphonenumber:libphonenumber:8.0.0'
+ testImplementation "com.google.truth:truth:0.42"
+ testImplementation 'com.googlecode.libphonenumber:libphonenumber:8.0.0'
} \ No newline at end of file
diff --git a/integration_tests/mockito-experimental/build.gradle b/integration_tests/mockito-experimental/build.gradle
index 4ff913436..0346926d9 100644
--- a/integration_tests/mockito-experimental/build.gradle
+++ b/integration_tests/mockito-experimental/build.gradle
@@ -1,16 +1,11 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
apply plugin: RoboJavaModulePlugin
dependencies {
- compile project(":robolectric")
+ api project(":robolectric")
compileOnly AndroidSdk.MAX_SDK.coordinates
- // Testing dependencies
testRuntime AndroidSdk.MAX_SDK.coordinates
- testCompile "junit:junit:4.12"
- testCompile "com.google.truth:truth:0.36"
- testCompile "org.mockito:mockito-core:2.5.4"
+ testImplementation "junit:junit:4.12"
+ testImplementation "com.google.truth:truth:0.42"
+ testImplementation "org.mockito:mockito-core:2.5.4"
} \ No newline at end of file
diff --git a/integration_tests/mockito/build.gradle b/integration_tests/mockito/build.gradle
index 2808ec920..0346926d9 100644
--- a/integration_tests/mockito/build.gradle
+++ b/integration_tests/mockito/build.gradle
@@ -1,16 +1,11 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
apply plugin: RoboJavaModulePlugin
dependencies {
- compile project(":robolectric")
+ api project(":robolectric")
compileOnly AndroidSdk.MAX_SDK.coordinates
- // Testing dependencies
testRuntime AndroidSdk.MAX_SDK.coordinates
- testCompile "junit:junit:4.12"
- testCompile "com.google.truth:truth:0.39"
- testCompile "org.mockito:mockito-core:2.5.4"
+ testImplementation "junit:junit:4.12"
+ testImplementation "com.google.truth:truth:0.42"
+ testImplementation "org.mockito:mockito-core:2.5.4"
} \ No newline at end of file
diff --git a/integration_tests/multidex/src/test/AndroidManifest.xml b/integration_tests/multidex/src/test/AndroidManifest.xml
new file mode 100644
index 000000000..c9bd6ab42
--- /dev/null
+++ b/integration_tests/multidex/src/test/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.robolectric.integration_tests.multidex">
+
+ <uses-sdk
+ android:minSdkVersion="16"
+ android:targetSdkVersion="27"/>
+
+ <application />
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="org.robolectric.integration_tests.multidex"/>
+
+</manifest>
diff --git a/integration_tests/multidex/src/test/java/org/robolectric/integration_tests/multidex/MultiDexTest.java b/integration_tests/multidex/src/test/java/org/robolectric/integration_tests/multidex/MultiDexTest.java
new file mode 100644
index 000000000..bc441a82f
--- /dev/null
+++ b/integration_tests/multidex/src/test/java/org/robolectric/integration_tests/multidex/MultiDexTest.java
@@ -0,0 +1,17 @@
+package org.robolectric.integration_tests.multidex;
+
+import android.support.multidex.MultiDex;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Integration tests for MultiDex Robolectric. */
+@RunWith(AndroidJUnit4.class)
+public class MultiDexTest {
+
+ @Test
+ public void testIntendedFailEmpty() {
+ MultiDex.install(ApplicationProvider.getApplicationContext());
+ }
+}
diff --git a/integration_tests/multidex/src/test/java/org/robolectric/integration_tests/multidex/robolectric.properties b/integration_tests/multidex/src/test/java/org/robolectric/integration_tests/multidex/robolectric.properties
new file mode 100644
index 000000000..5b66826f3
--- /dev/null
+++ b/integration_tests/multidex/src/test/java/org/robolectric/integration_tests/multidex/robolectric.properties
@@ -0,0 +1,3 @@
+sdk=ALL_SDKS
+# make Robolectric match the emulator used
+qualifiers=w480dp-h800dp
diff --git a/integration_tests/powermock/build.gradle b/integration_tests/powermock/build.gradle
index 53a86e562..66af18c86 100644
--- a/integration_tests/powermock/build.gradle
+++ b/integration_tests/powermock/build.gradle
@@ -1,20 +1,15 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
apply plugin: RoboJavaModulePlugin
dependencies {
- compile project(":robolectric")
+ api project(":robolectric")
compileOnly AndroidSdk.MAX_SDK.coordinates
- // Testing dependencies
testRuntime AndroidSdk.MAX_SDK.coordinates
- testCompile "junit:junit:4.12"
- testCompile "com.google.truth:truth:0.39"
+ testImplementation "junit:junit:4.12"
+ testImplementation "com.google.truth:truth:0.42"
- testCompile "org.powermock:powermock-module-junit4:1.6.6"
- testCompile "org.powermock:powermock-module-junit4-rule:1.6.6"
- testCompile "org.powermock:powermock-api-mockito:1.6.6"
- testCompile "org.powermock:powermock-classloading-xstream:1.6.6"
+ testImplementation "org.powermock:powermock-module-junit4:1.6.6"
+ testImplementation "org.powermock:powermock-module-junit4-rule:1.6.6"
+ testImplementation "org.powermock:powermock-api-mockito:1.6.6"
+ testImplementation "org.powermock:powermock-classloading-xstream:1.6.6"
} \ No newline at end of file
diff --git a/junit/build.gradle b/junit/build.gradle
index 7b246e075..8d5bcac69 100644
--- a/junit/build.gradle
+++ b/junit/build.gradle
@@ -1,17 +1,12 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
dependencies {
- // Compile dependencies
- compile project(":annotations")
- compile project(":sandbox")
- compile project(":shadowapi")
+ api project(":annotations")
+ api project(":sandbox")
+ api project(":shadowapi")
- compileOnly "com.google.code.findbugs:jsr305:3.0.1"
+ compileOnly "com.google.code.findbugs:jsr305:3.0.2"
compileOnly "junit:junit:4.12"
-} \ No newline at end of file
+}
diff --git a/processor/build.gradle b/processor/build.gradle
index e74588dc1..ebdb4b780 100644
--- a/processor/build.gradle
+++ b/processor/build.gradle
@@ -1,7 +1,3 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
@@ -35,30 +31,18 @@ task('generateSdksFile', type: GenerateSdksFileTask) {
tasks['classes'].dependsOn(generateSdksFile)
-// Disable annotation processor for tests
-compileTestJava {
- options.compilerArgs.add("-proc:none")
-}
-
dependencies {
- // Project dependencies
- compile project(":annotations")
+ implementation project(":annotations")
- // Compile dependencies
- compile "com.google.guava:guava:20.0"
- compileOnly "com.google.code.findbugs:jsr305:3.0.1"
- compile "com.google.code.gson:gson:2.8.0"
- compile 'ch.raffael.pegdown-doclet:pegdown-doclet:1.3'
+ compileOnly "com.google.code.findbugs:jsr305:3.0.2"
+ implementation "com.google.guava:guava:20.0"
+ implementation "com.google.code.gson:gson:2.8.2"
+ implementation 'ch.raffael.pegdown-doclet:pegdown-doclet:1.3'
- // in jdk 9, tools.jar disappears!
- def toolsJar = org.gradle.internal.jvm.Jvm.current().getToolsJar()
- if (toolsJar != null) {
- compile files(toolsJar)
- }
+ implementation files(org.gradle.internal.jvm.Jvm.current().getToolsJar())
- // Testing dependencies
- testCompile "junit:junit:4.12"
- testCompile "org.mockito:mockito-core:2.5.4"
- testCompile "com.google.testing.compile:compile-testing:0.15"
- testCompile "com.google.truth:truth:0.42"
+ testImplementation "junit:junit:4.12"
+ testImplementation "org.mockito:mockito-core:2.5.4"
+ testImplementation "com.google.testing.compile:compile-testing:0.15"
+ testImplementation "com.google.truth:truth:0.42"
}
diff --git a/processor/src/main/java/org/robolectric/annotation/processing/validator/ImplementsValidator.java b/processor/src/main/java/org/robolectric/annotation/processing/validator/ImplementsValidator.java
index f9a790ccc..ee92a7f2e 100644
--- a/processor/src/main/java/org/robolectric/annotation/processing/validator/ImplementsValidator.java
+++ b/processor/src/main/java/org/robolectric/annotation/processing/validator/ImplementsValidator.java
@@ -66,13 +66,7 @@ public class ImplementsValidator extends Validator {
private TypeElement getClassNameTypeElement(AnnotationValue cv) {
String className = Helpers.getAnnotationStringValue(cv);
- TypeElement type = elements.getTypeElement(className.replace('$', '.'));
-
- if (type == null) {
- error("@Implements: could not resolve class <" + className + '>', cv);
- return null;
- }
- return type;
+ return elements.getTypeElement(className.replace('$', '.'));
}
@Override
@@ -104,17 +98,7 @@ public class ImplementsValidator extends Validator {
// This shadow doesn't apply to the current SDK. todo: check each SDK.
if (maxSdk != -1 && maxSdk < MAX_SUPPORTED_ANDROID_SDK) {
- String sdkClassName;
- if (av == null) {
- sdkClassName = Helpers.getAnnotationStringValue(cv).replace('$', '.');
- } else {
- sdkClassName = av.toString();
- }
-
- // there's no such type at the current SDK level, so just use strings...
- // getQualifiedName() uses Outer.Inner and we want Outer$Inner, so:
- String name = getClassFQName(shadowType);
- modelBuilder.addExtraShadow(sdkClassName, name);
+ addShadowNotInSdk(shadowType, av, cv);
return null;
}
@@ -125,6 +109,12 @@ public class ImplementsValidator extends Validator {
return null;
}
actualType = getClassNameTypeElement(cv);
+
+ if (actualType == null
+ && !suppressWarnings(shadowType, "robolectric.internal.IgnoreMissingClass")) {
+ error("@Implements: could not resolve class <" + cv + '>', cv);
+ return null;
+ }
} else {
TypeMirror value = Helpers.getAnnotationTypeMirrorValue(av);
if (value == null) {
@@ -137,6 +127,7 @@ public class ImplementsValidator extends Validator {
}
}
if (actualType == null) {
+ addShadowNotInSdk(shadowType, av, cv);
return null;
}
final List<? extends TypeParameterElement> typeTP = actualType.getTypeParameters();
@@ -173,6 +164,32 @@ public class ImplementsValidator extends Validator {
return null;
}
+ private void addShadowNotInSdk(TypeElement shadowType, AnnotationValue av, AnnotationValue cv) {
+ String sdkClassName;
+ if (av == null) {
+ sdkClassName = Helpers.getAnnotationStringValue(cv).replace('$', '.');
+ } else {
+ sdkClassName = av.toString();
+ }
+
+ // there's no such type at the current SDK level, so just use strings...
+ // getQualifiedName() uses Outer.Inner and we want Outer$Inner, so:
+ String name = getClassFQName(shadowType);
+ modelBuilder.addExtraShadow(sdkClassName, name);
+ }
+
+ private static boolean suppressWarnings(Element element, String warningName) {
+ SuppressWarnings[] suppressWarnings = element.getAnnotationsByType(SuppressWarnings.class);
+ for (SuppressWarnings suppression : suppressWarnings) {
+ for (String name : suppression.value()) {
+ if (warningName.equals(name)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
static String getClassFQName(TypeElement elem) {
StringBuilder name = new StringBuilder();
while (isClassy(elem.getEnclosingElement().getKind())) {
diff --git a/processor/src/main/java/org/robolectric/annotation/processing/validator/SdkStore.java b/processor/src/main/java/org/robolectric/annotation/processing/validator/SdkStore.java
index c65076e78..e01674dba 100644
--- a/processor/src/main/java/org/robolectric/annotation/processing/validator/SdkStore.java
+++ b/processor/src/main/java/org/robolectric/annotation/processing/validator/SdkStore.java
@@ -99,6 +99,20 @@ class SdkStore {
}
}
+ private static String canonicalize(TypeMirror typeMirror) {
+ if (typeMirror instanceof TypeVar) {
+ return ((TypeVar) typeMirror).getUpperBound().toString();
+ } else if (typeMirror instanceof ArrayType) {
+ return canonicalize(((ArrayType) typeMirror).elemtype) + "[]";
+ } else {
+ return typeMirror.toString();
+ }
+ }
+
+ private static String typeWithoutGenerics(String paramType) {
+ return paramType.replaceAll("<.*", "");
+ }
+
static class Sdk implements Comparable<Sdk> {
private static final ClassInfo NULL_CLASS_INFO = new ClassInfo();
@@ -138,22 +152,61 @@ class SdkStore {
}
MethodExtraInfo implMethod = new MethodExtraInfo(methodElement);
- if (sdkMethod.equals(implMethod)) {
+ if (!sdkMethod.equals(implMethod)
+ && !suppressWarnings(methodElement, "robolectric.ShadowReturnTypeMismatch")) {
if (implMethod.isStatic != sdkMethod.isStatic) {
return "@Implementation for " + methodElement.getSimpleName()
+ " is " + (implMethod.isStatic ? "static" : "not static")
+ " unlike the SDK method";
}
if (!implMethod.returnType.equals(sdkMethod.returnType)) {
- return "@Implementation for " + methodElement.getSimpleName()
- + " has a return type of " + implMethod.returnType
- + ", not " + sdkMethod.returnType + " as in the SDK method";
+ if (
+ (looseSignatures && typeIsOkForLooseSignatures(implMethod, sdkMethod))
+ || (looseSignatures && implMethod.returnType.equals("java.lang.Object[]"))
+ // Number is allowed for int or long return types
+ || typeIsNumeric(sdkMethod, implMethod)) {
+ return null;
+ } else {
+ return "@Implementation for " + methodElement.getSimpleName()
+ + " has a return type of " + implMethod.returnType
+ + ", not " + sdkMethod.returnType + " as in the SDK method";
+ }
}
}
return null;
}
+ private boolean suppressWarnings(ExecutableElement methodElement, String warningName) {
+ SuppressWarnings[] suppressWarnings = methodElement.getAnnotationsByType(SuppressWarnings.class);
+ for (SuppressWarnings suppression : suppressWarnings) {
+ for (String name : suppression.value()) {
+ if (warningName.equals(name)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean typeIsNumeric(MethodExtraInfo sdkMethod, MethodExtraInfo implMethod) {
+ return implMethod.returnType.equals("java.lang.Number")
+ && isNumericType(sdkMethod.returnType);
+ }
+
+ private boolean typeIsOkForLooseSignatures(MethodExtraInfo implMethod, MethodExtraInfo sdkMethod) {
+ return
+ // loose signatures allow a return type of Object...
+ implMethod.returnType.equals("java.lang.Object")
+ // or Object[] for arrays...
+ || (implMethod.returnType.equals("java.lang.Object[]")
+ && sdkMethod.returnType.endsWith("[]"));
+ }
+
+ private boolean isNumericType(String type) {
+ return type.equals("int") || type.equals("long");
+ }
+
/**
* Load and analyze bytecode for the specified class, with caching.
*
@@ -293,7 +346,7 @@ class SdkStore {
public MethodInfo(MethodNode method) {
this.name = method.name;
for (Type type : Type.getArgumentTypes(method.desc)) {
- paramTypes.add(type.getClassName().replace('$', '.'));
+ paramTypes.add(normalize(type));
}
}
@@ -312,21 +365,11 @@ class SdkStore {
for (VariableElement variableElement : methodElement.getParameters()) {
TypeMirror varTypeMirror = variableElement.asType();
String paramType = canonicalize(varTypeMirror);
- String paramTypeWithoutGenerics = paramType.replaceAll("<.*", "");
+ String paramTypeWithoutGenerics = typeWithoutGenerics(paramType);
paramTypes.add(paramTypeWithoutGenerics);
}
}
- private String canonicalize(TypeMirror typeMirror) {
- if (typeMirror instanceof TypeVar) {
- return ((TypeVar) typeMirror).getUpperBound().toString();
- } else if (typeMirror instanceof ArrayType) {
- return canonicalize(((ArrayType) typeMirror).elemtype) + "[]";
- } else {
- return typeMirror.toString();
- }
- }
-
private String cleanMethodName(ExecutableElement methodElement) {
String name = methodElement.getSimpleName().toString();
if (CONSTRUCTOR_METHOD_NAME.equals(name)) {
@@ -359,7 +402,6 @@ class SdkStore {
public int hashCode() {
return Objects.hash(name, paramTypes);
}
-
@Override
public String toString() {
return "MethodInfo{"
@@ -369,18 +411,40 @@ class SdkStore {
}
}
+ private static String normalize(Type type) {
+ return type.getClassName().replace('$', '.');
+ }
+
static class MethodExtraInfo {
private final boolean isStatic;
private final String returnType;
public MethodExtraInfo(MethodNode method) {
this.isStatic = (method.access & Opcodes.ACC_STATIC) != 0;
- this.returnType = Type.getReturnType(method.desc).getClassName();
+ this.returnType = typeWithoutGenerics(normalize(Type.getReturnType(method.desc)));
}
public MethodExtraInfo(ExecutableElement methodElement) {
this.isStatic = methodElement.getModifiers().contains(Modifier.STATIC);
- this.returnType = methodElement.getReturnType().toString();
+ this.returnType = typeWithoutGenerics(canonicalize(methodElement.getReturnType()));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ MethodExtraInfo that = (MethodExtraInfo) o;
+ return isStatic == that.isStatic &&
+ Objects.equals(returnType, that.returnType);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(isStatic, returnType);
}
}
}
diff --git a/resources/build.gradle b/resources/build.gradle
index 42f221819..1ce690698 100644
--- a/resources/build.gradle
+++ b/resources/build.gradle
@@ -1,23 +1,16 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
dependencies {
- // Project dependencies
- compile project(":utils")
- compile project(":annotations")
+ api project(":utils")
+ api project(":annotations")
- // Compile dependencies
- compile "com.google.guava:guava:20.0"
- compileOnly "com.google.code.findbugs:jsr305:3.0.1"
+ api "com.google.guava:guava:20.0"
+ compileOnly "com.google.code.findbugs:jsr305:3.0.2"
- // Testing dependencies
- testCompile "junit:junit:4.12"
- testCompile "com.google.truth:truth:0.39"
- testCompile "com.google.testing.compile:compile-testing:0.6"
- testCompile "org.mockito:mockito-core:2.5.4"
+ testImplementation "junit:junit:4.12"
+ testImplementation "com.google.truth:truth:0.42"
+ testImplementation "com.google.testing.compile:compile-testing:0.6"
+ testImplementation "org.mockito:mockito-core:2.5.4"
}
diff --git a/resources/src/main/java/org/robolectric/RoboSettings.java b/resources/src/main/java/org/robolectric/RoboSettings.java
index 3ca247618..3dc800ab5 100644
--- a/resources/src/main/java/org/robolectric/RoboSettings.java
+++ b/resources/src/main/java/org/robolectric/RoboSettings.java
@@ -7,11 +7,15 @@ public class RoboSettings {
private static String mavenRepositoryId;
private static String mavenRepositoryUrl;
+ private static String mavenRepositoryUserName;
+ private static String mavenRepositoryPassword;
private static boolean useGlobalScheduler;
static {
mavenRepositoryId = System.getProperty("robolectric.dependency.repo.id", "sonatype");
mavenRepositoryUrl = System.getProperty("robolectric.dependency.repo.url", "https://oss.sonatype.org/content/groups/public/");
+ mavenRepositoryUserName = System.getProperty("robolectric.dependency.repo.username");
+ mavenRepositoryPassword = System.getProperty("robolectric.dependency.repo.password");
useGlobalScheduler = Boolean.getBoolean("robolectric.scheduling.global");
}
@@ -31,6 +35,22 @@ public class RoboSettings {
RoboSettings.mavenRepositoryUrl = mavenRepositoryUrl;
}
+ public static String getMavenRepositoryUserName() {
+ return mavenRepositoryUserName;
+ }
+
+ public static void setMavenRepositoryUserName(String mavenRepositoryUserName) {
+ RoboSettings.mavenRepositoryUserName = mavenRepositoryUserName;
+ }
+
+ public static String getMavenRepositoryPassword() {
+ return mavenRepositoryPassword;
+ }
+
+ public static void setMavenRepositoryPassword(String mavenRepositoryPassword) {
+ RoboSettings.mavenRepositoryPassword = mavenRepositoryPassword;
+ }
+
public static boolean isUseGlobalScheduler() {
return useGlobalScheduler;
}
diff --git a/resources/src/main/java/org/robolectric/manifest/AndroidManifest.java b/resources/src/main/java/org/robolectric/manifest/AndroidManifest.java
index 57def481c..7bb8862a6 100644
--- a/resources/src/main/java/org/robolectric/manifest/AndroidManifest.java
+++ b/resources/src/main/java/org/robolectric/manifest/AndroidManifest.java
@@ -284,11 +284,11 @@ public class AndroidManifest implements UsesSdk {
List<PathPermissionData> pathPermissionDatas = new ArrayList<>();
for (Node node : getChildrenTags(contentProviderNode, "path-permission")) {
pathPermissionDatas.add(new PathPermissionData(
- getAttributeValue(node, "android:path"),
- getAttributeValue(node, "android:pathPrefix"),
- getAttributeValue(node, "android:pathPattern"),
- getAttributeValue(node, "android:readPermission"),
- getAttributeValue(node, "android:writePermission")
+ getAttributeValue(node, "android:path"),
+ getAttributeValue(node, "android:pathPrefix"),
+ getAttributeValue(node, "android:pathPattern"),
+ getAttributeValue(node, "android:readPermission"),
+ getAttributeValue(node, "android:writePermission")
));
}
@@ -297,10 +297,8 @@ public class AndroidManifest implements UsesSdk {
resolveClassRef(name),
metaData,
authorities,
- getAttributeValue(contentProviderNode, "android:readPermission"),
- getAttributeValue(contentProviderNode, "android:writePermission"),
- pathPermissionDatas,
- getAttributeValue(contentProviderNode, "android:grantUriPermissions")));
+ parseNodeAttributes(contentProviderNode),
+ pathPermissionDatas));
}
}
diff --git a/resources/src/main/java/org/robolectric/manifest/BroadcastReceiverData.java b/resources/src/main/java/org/robolectric/manifest/BroadcastReceiverData.java
index 7361beb94..41539a456 100644
--- a/resources/src/main/java/org/robolectric/manifest/BroadcastReceiverData.java
+++ b/resources/src/main/java/org/robolectric/manifest/BroadcastReceiverData.java
@@ -10,6 +10,7 @@ public class BroadcastReceiverData extends PackageItemData {
private static final String EXPORTED = "android:exported";
private static final String NAME = "android:name";
private static final String PERMISSION = "android:permission";
+ private static final String ENABLED = "android:enabled";
private final Map<String, String> attributes;
private final List<String> actions;
@@ -75,4 +76,8 @@ public class BroadcastReceiverData extends PackageItemData {
? Boolean.parseBoolean(attributes.get(EXPORTED))
: defaultValue);
}
+
+ public boolean isEnabled() {
+ return attributes.containsKey(ENABLED) ? Boolean.parseBoolean(attributes.get(ENABLED)) : true;
+ }
}
diff --git a/resources/src/main/java/org/robolectric/manifest/ContentProviderData.java b/resources/src/main/java/org/robolectric/manifest/ContentProviderData.java
index 1db52c926..b1c063a0b 100644
--- a/resources/src/main/java/org/robolectric/manifest/ContentProviderData.java
+++ b/resources/src/main/java/org/robolectric/manifest/ContentProviderData.java
@@ -1,28 +1,28 @@
package org.robolectric.manifest;
import java.util.List;
+import java.util.Map;
public class ContentProviderData extends PackageItemData {
+ private static final String READ_PERMISSION = "android:readPermission";
+ private static final String WRITE_PERMISSION = "android:writePermission";
+ private static final String GRANT_URI_PERMISSION = "android:grantUriPermissions";
+ private static final String ENABLED = "android:enabled";
+
private final String authority;
- private final String readPermission;
- private final String writePermission;
+ private final Map<String, String> attributes;
private final List<PathPermissionData> pathPermissionDatas;
- private final boolean grantUriPermissions;
public ContentProviderData(
String className,
MetaData metaData,
String authority,
- String readPermission,
- String writePermission,
- List<PathPermissionData> pathPermissionDatas,
- String grantUriPermissions) {
+ Map<String, String> attributes,
+ List<PathPermissionData> pathPermissionDatas) {
super(className, metaData);
this.authority = authority;
- this.readPermission = readPermission;
- this.writePermission = writePermission;
+ this.attributes = attributes;
this.pathPermissionDatas = pathPermissionDatas;
- this.grantUriPermissions = Boolean.parseBoolean(grantUriPermissions);
}
public String getAuthorities() {
@@ -30,11 +30,11 @@ public class ContentProviderData extends PackageItemData {
}
public String getReadPermission() {
- return readPermission;
+ return attributes.get(READ_PERMISSION);
}
public String getWritePermission() {
- return writePermission;
+ return attributes.get(WRITE_PERMISSION);
}
public List<PathPermissionData> getPathPermissionDatas() {
@@ -42,6 +42,10 @@ public class ContentProviderData extends PackageItemData {
}
public boolean getGrantUriPermissions() {
- return grantUriPermissions;
+ return Boolean.parseBoolean(attributes.get(GRANT_URI_PERMISSION));
+ }
+
+ public boolean isEnabled() {
+ return attributes.containsKey(ENABLED) ? Boolean.parseBoolean(attributes.get(ENABLED)) : true;
}
}
diff --git a/resources/src/main/java/org/robolectric/manifest/ServiceData.java b/resources/src/main/java/org/robolectric/manifest/ServiceData.java
index 64ac10643..82f9d8777 100644
--- a/resources/src/main/java/org/robolectric/manifest/ServiceData.java
+++ b/resources/src/main/java/org/robolectric/manifest/ServiceData.java
@@ -12,6 +12,7 @@ public class ServiceData extends PackageItemData {
private static final String EXPORTED = "android:exported";
private static final String NAME = "android:name";
private static final String PERMISSION = "android:permission";
+ private static final String ENABLED = "android:enabled";
private final Map<String, String> attributes;
private final List<String> actions;
@@ -70,4 +71,8 @@ public class ServiceData extends PackageItemData {
? Boolean.parseBoolean(attributes.get(EXPORTED))
: defaultValue);
}
+
+ public boolean isEnabled() {
+ return attributes.containsKey(ENABLED) ? Boolean.parseBoolean(attributes.get(ENABLED)) : true;
+ }
}
diff --git a/resources/src/main/java/org/robolectric/res/android/AConfiguration.java b/resources/src/main/java/org/robolectric/res/android/AConfiguration.java
index 0fa6bd298..0aca39044 100644
--- a/resources/src/main/java/org/robolectric/res/android/AConfiguration.java
+++ b/resources/src/main/java/org/robolectric/res/android/AConfiguration.java
@@ -1,8 +1,8 @@
package org.robolectric.res.android;
-// transliterated from https://android.googlesource.com/platform/frameworks/native/+/android-9.0.0_r3/include/android/configuration.h
+// transliterated from https://android.googlesource.com/platform/frameworks/native/+/android-9.0.0_r12/include/android/configuration.h
public class AConfiguration {
-/** Orientation: not specified. */
+ /** Orientation: not specified. */
public static final int ACONFIGURATION_ORIENTATION_ANY = 0x0000;
/**
* Orientation: value corresponding to the
@@ -275,10 +275,10 @@ public class AConfiguration {
* <a href="@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier">watch</a> resource qualifier specified.
*/
public static final int ACONFIGURATION_UI_MODE_TYPE_WATCH = 0x06;
- /**
- * UI mode: value that corresponds to
- * <a href="@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier">vr</a> resource qualifier specified.
- */
+ /**
+ * UI mode: value that corresponds to
+ * <a href="@dacRoot/guide/topics/resources/providing-resources.html#UiModeQualifier">vr</a> resource qualifier specified.
+ */
public static final int ACONFIGURATION_UI_MODE_TYPE_VR_HEADSET = 0x07;
/** UI night mode: not specified.*/
public static final int ACONFIGURATION_UI_MODE_NIGHT_ANY = 0x00;
diff --git a/resources/src/main/java/org/robolectric/res/android/Asset.java b/resources/src/main/java/org/robolectric/res/android/Asset.java
index 7417963b9..4484884e8 100644
--- a/resources/src/main/java/org/robolectric/res/android/Asset.java
+++ b/resources/src/main/java/org/robolectric/res/android/Asset.java
@@ -17,6 +17,8 @@ import java.util.zip.ZipFile;
import org.robolectric.res.FileTypedResource;
import org.robolectric.res.FsFile;
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/Asset.cpp
+// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/include/androidfw/Asset.h
/*
* Instances of this class provide read-only operations on a byte stream.
*
@@ -100,14 +102,14 @@ public abstract class Asset {
*/
public abstract long seek(long offset, int whence);
- /*
- * Close the asset, freeing all associated resources.
- */
- public abstract void close();
+ /*
+ * Close the asset, freeing all associated resources.
+ */
+ public abstract void close();
- /*
- * Get a pointer to a buffer with the entire contents of the file.
- */
+ /*
+ * Get a pointer to a buffer with the entire contents of the file.
+ */
public abstract byte[] getBuffer(boolean wordAligned);
/*
@@ -120,11 +122,11 @@ public abstract class Asset {
*/
public abstract long getRemainingLength();
- /*
- * Open a new file descriptor that can be used to read this asset.
- * Returns -1 if you can not use the file descriptor (for example if the
- * asset is compressed).
- */
+ /*
+ * Open a new file descriptor that can be used to read this asset.
+ * Returns -1 if you can not use the file descriptor (for example if the
+ * asset is compressed).
+ */
public abstract FileDescriptor openFileDescriptor(Ref<Long> outStart, Ref<Long> outLength);
public abstract File getFile();
@@ -253,43 +255,43 @@ public abstract class Asset {
void registerAsset(Asset asset)
{
- // AutoMutex _l(gAssetLock);
- // gCount++;
- // asset.mNext = asset.mPrev = null;
- // if (gTail == null) {
- // gHead = gTail = asset;
- // } else {
- // asset.mPrev = gTail;
- // gTail.mNext = asset;
- // gTail = asset;
- // }
- //
- // if (kIsDebug) {
- // ALOGI("Creating Asset %s #%d\n", asset, gCount);
- // }
+ // AutoMutex _l(gAssetLock);
+ // gCount++;
+ // asset.mNext = asset.mPrev = null;
+ // if (gTail == null) {
+ // gHead = gTail = asset;
+ // } else {
+ // asset.mPrev = gTail;
+ // gTail.mNext = asset;
+ // gTail = asset;
+ // }
+ //
+ // if (kIsDebug) {
+ // ALOGI("Creating Asset %s #%d\n", asset, gCount);
+ // }
}
void unregisterAsset(Asset asset)
{
- // AutoMutex _l(gAssetLock);
- // gCount--;
- // if (gHead == asset) {
- // gHead = asset.mNext;
- // }
- // if (gTail == asset) {
- // gTail = asset.mPrev;
- // }
- // if (asset.mNext != null) {
- // asset.mNext.mPrev = asset.mPrev;
- // }
- // if (asset.mPrev != null) {
- // asset.mPrev.mNext = asset.mNext;
- // }
- // asset.mNext = asset.mPrev = null;
- //
- // if (kIsDebug) {
- // ALOGI("Destroying Asset in %s #%d\n", asset, gCount);
- // }
+ // AutoMutex _l(gAssetLock);
+ // gCount--;
+ // if (gHead == asset) {
+ // gHead = asset.mNext;
+ // }
+ // if (gTail == asset) {
+ // gTail = asset.mPrev;
+ // }
+ // if (asset.mNext != null) {
+ // asset.mNext.mPrev = asset.mPrev;
+ // }
+ // if (asset.mPrev != null) {
+ // asset.mPrev.mNext = asset.mNext;
+ // }
+ // asset.mNext = asset.mPrev = null;
+ //
+ // if (kIsDebug) {
+ // ALOGI("Destroying Asset in %s #%d\n", asset, gCount);
+ // }
}
public static int getGlobalCount()
@@ -510,7 +512,7 @@ public abstract class Asset {
/*
* Create a new Asset from compressed data in a memory mapping.
*/
-static Asset createFromCompressedMap(FileMap dataMap,
+ static Asset createFromCompressedMap(FileMap dataMap,
int uncompressedLen, AccessMode mode)
{
_CompressedAsset pAsset;
@@ -601,7 +603,7 @@ static Asset createFromCompressedMap(FileMap dataMap,
@Override
public long getRemainingLength() { return mLength-mOffset; }
-// virtual int openFileDescriptor(long* outStart, long* outLength) final;
+ // virtual int openFileDescriptor(long* outStart, long* outLength) final;
@Override
boolean isAllocated() { return mBuf != null; }
@@ -629,18 +631,18 @@ static Asset createFromCompressedMap(FileMap dataMap,
* just read them in.
*/
// enum {
- public static int kReadVsMapThreshold = 4096;
+ public static int kReadVsMapThreshold = 4096;
// };
FileMap mMap; // for memory map
byte[] mBuf; // for read
// final void* ensureAlignment(FileMap map);
-/*
- * ===========================================================================
- * _FileAsset
- * ===========================================================================
- */
+ /*
+ * ===========================================================================
+ * _FileAsset
+ * ===========================================================================
+ */
/*
* Constructor.
@@ -742,12 +744,12 @@ static Asset createFromCompressedMap(FileMap dataMap,
assert(mOffset >= 0 && mOffset <= mLength);
if (getAccessMode() == ACCESS_BUFFER) {
- /*
- * On first access, read or map the entire file. The caller has
- * requested buffer access, either because they're going to be
- * using the buffer or because what they're doing has appropriate
- * performance needs and access patterns.
- */
+ /*
+ * On first access, read or map the entire file. The caller has
+ * requested buffer access, either because they're going to be
+ * using the buffer or because what they're doing has appropriate
+ * performance needs and access patterns.
+ */
if (mBuf == null)
getBuffer(false);
}
@@ -762,19 +764,19 @@ static Asset createFromCompressedMap(FileMap dataMap,
}
if (mMap != null) {
- /* copy from mapped area */
+ /* copy from mapped area */
//printf("map read\n");
// memcpy(buf, (String)mMap.getDataPtr() + mOffset, count);
System.arraycopy(mMap.getDataPtr(), toIntExact(mOffset), buf, bufOffset, count);
actual = count;
} else if (mBuf != null) {
- /* copy from buffer */
+ /* copy from buffer */
//printf("buf read\n");
// memcpy(buf, (String)mBuf + mOffset, count);
System.arraycopy(mBuf, toIntExact(mOffset), buf, bufOffset, count);
actual = count;
} else {
- /* read from the file */
+ /* read from the file */
//printf("file read\n");
// if (ftell(mFp) != mStart + mOffset) {
try {
@@ -873,7 +875,7 @@ static Asset createFromCompressedMap(FileMap dataMap,
return mBuf;
if (mMap != null) {
// if (!wordAligned) {
- return mMap.getDataPtr();
+ return mMap.getDataPtr();
// }
// return ensureAlignment(mMap);
}
@@ -884,8 +886,8 @@ static Asset createFromCompressedMap(FileMap dataMap,
byte[] buf;
int allocLen;
- /* zero-length files are allowed; not sure about zero-len allocs */
- /* (works fine with gcc + x86linux) */
+ /* zero-length files are allowed; not sure about zero-len allocs */
+ /* (works fine with gcc + x86linux) */
allocLen = toIntExact(mLength);
if (mLength == 0)
allocLen = 1;
@@ -1113,11 +1115,11 @@ static Asset createFromCompressedMap(FileMap dataMap,
// class StreamingZipInflater mZipInflater; // for streaming large compressed assets
byte[] mBuf; // for getBuffer()
-/*
- * ===========================================================================
- * _CompressedAsset
- * ===========================================================================
- */
+ /*
+ * ===========================================================================
+ * _CompressedAsset
+ * ===========================================================================
+ */
/*
* Constructor.
@@ -1232,7 +1234,7 @@ static Asset createFromCompressedMap(FileMap dataMap,
assert(mOffset >= 0 && mOffset <= mUncompressedLen);
- /* If we're relying on a streaming inflater, go through that */
+ /* If we're relying on a streaming inflater, go through that */
// if (mZipInflater) {
// actual = mZipInflater.read(buf, count);
// } else {
@@ -1275,7 +1277,7 @@ static Asset createFromCompressedMap(FileMap dataMap,
// compute new position within chunk
newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen);
if (newPosn == (long) -1)
- return newPosn;
+ return newPosn;
// if (mZipInflater) {
// mZipInflater.seekAbsolute(newPosn);
@@ -1289,21 +1291,21 @@ static Asset createFromCompressedMap(FileMap dataMap,
*/
@Override
public void close() {
- if (mMap != null) {
+ if (mMap != null) {
// delete mMap;
- mMap = null;
- }
+ mMap = null;
+ }
// delete[] mBuf;
- mBuf = null;
+ mBuf = null;
// delete mZipInflater;
// mZipInflater = null;
- if (mFd > 0) {
+ if (mFd > 0) {
// ::close(mFd);
- mFd = -1;
- }
+ mFd = -1;
+ }
}
/*
diff --git a/resources/src/main/java/org/robolectric/res/android/AssetDir.java b/resources/src/main/java/org/robolectric/res/android/AssetDir.java
index f7ef778e6..ea3d10bf6 100644
--- a/resources/src/main/java/org/robolectric/res/android/AssetDir.java
+++ b/resources/src/main/java/org/robolectric/res/android/AssetDir.java
@@ -2,8 +2,8 @@ package org.robolectric.res.android;
import org.robolectric.res.android.CppAssetManager.FileType;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/AssetDir.cpp and
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/include/androidfw/AssetDir.h
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/AssetDir.cpp and
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/include/androidfw/AssetDir.h
public class AssetDir {
private SortedVector<FileInfo> mFileInfo;
@@ -17,8 +17,8 @@ public class AssetDir {
}
/*
- * Vector-style access.
- */
+ * Vector-style access.
+ */
public int getFileCount() {
return mFileInfo.size();
}
@@ -49,8 +49,8 @@ public class AssetDir {
FileInfo() {}
FileInfo(String8 path) { // useful for e.g. svect.indexOf
- mFileName = path;
- mFileType = FileType.kFileTypeUnknown;
+ mFileName = path;
+ mFileType = FileType.kFileTypeUnknown;
}
FileInfo(FileInfo src) {
@@ -106,7 +106,7 @@ public class AssetDir {
* Returns the index of the matching entry, or -1 if none found.
*/
static int findEntry(SortedVector<FileInfo> pVector,
- String8 fileName) {
+ String8 fileName) {
FileInfo tmpInfo = new FileInfo();
tmpInfo.setFileName(fileName);
diff --git a/resources/src/main/java/org/robolectric/res/android/AttributeResolution9.java b/resources/src/main/java/org/robolectric/res/android/AttributeResolution9.java
index 33cd5d01c..972f4b6fd 100644
--- a/resources/src/main/java/org/robolectric/res/android/AttributeResolution9.java
+++ b/resources/src/main/java/org/robolectric/res/android/AttributeResolution9.java
@@ -11,8 +11,8 @@ import org.robolectric.res.android.CppAssetManager2.Theme;
import org.robolectric.res.android.ResourceTypes.Res_value;
// transliterated from
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/AttributeResolution.cpp and
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/include/androidfw/AttributeResolution.h
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/AttributeResolution.cpp and
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/include/androidfw/AttributeResolution.h
public class AttributeResolution9 {
public static final boolean kThrowOnBadId = false;
@@ -87,9 +87,9 @@ public class AttributeResolution9 {
// `out_values` must NOT be nullptr.
// `out_indices` may be nullptr.
public static boolean ResolveAttrs(Theme theme, int def_style_attr,
- int def_style_res, int[] src_values,
- int src_values_length, int[] attrs,
- int attrs_length, int[] out_values, int[] out_indices) {
+ int def_style_res, int[] src_values,
+ int src_values_length, int[] attrs,
+ int attrs_length, int[] out_values, int[] out_indices) {
if (kDebugStyles) {
ALOGI("APPLY STYLE: theme=0x%p defStyleAttr=0x%x defStyleRes=0x%x", theme,
def_style_attr, def_style_res);
@@ -235,8 +235,8 @@ public class AttributeResolution9 {
}
public static void ApplyStyle(Theme theme, ResXMLParser xml_parser, int def_style_attr,
- int def_style_resid, int[] attrs, int attrs_length,
- int[] out_values, int[] out_indices) {
+ int def_style_resid, int[] attrs, int attrs_length,
+ int[] out_values, int[] out_indices) {
if (kDebugStyles) {
ALOGI("APPLY STYLE: theme=%s defStyleAttr=0x%x defStyleRes=0x%x xml=%s",
theme, def_style_attr, def_style_resid, xml_parser);
@@ -353,7 +353,7 @@ public class AttributeResolution9 {
// We found the attribute we were looking for.
cookie = entry.cookie;
type_set_flags.set(def_style_flags.get());
-
+
value.set(entry.value);
if (kDebugStyles) {
ALOGI("-> From def style: type=0x%x, data=0x%08x", value.get().dataType, value.get().data);
diff --git a/resources/src/main/java/org/robolectric/res/android/ByteBucketArray.java b/resources/src/main/java/org/robolectric/res/android/ByteBucketArray.java
index 2c280eb18..209fb1ee8 100644
--- a/resources/src/main/java/org/robolectric/res/android/ByteBucketArray.java
+++ b/resources/src/main/java/org/robolectric/res/android/ByteBucketArray.java
@@ -1,11 +1,15 @@
package org.robolectric.res.android;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/include/androidfw/ByteBucketArray.h
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/include/androidfw/ByteBucketArray.h
/**
* Stores a sparsely populated array. Has a fixed size of 256
* (number of entries that a byte can represent).
*/
public abstract class ByteBucketArray<T> {
+ public ByteBucketArray(T mDefault) {
+ this.mDefault = mDefault;
+ }
+
final int size() {
return NUM_BUCKETS * BUCKET_SIZE;
}
@@ -25,7 +29,8 @@ public abstract class ByteBucketArray<T> {
if (bucket == null) {
return mDefault;
}
- return bucket[0x0f & ((byte) index)];
+ T t = bucket[0x0f & ((byte) index)];
+ return t == null ? mDefault : t;
}
T editItemAt(int index) {
diff --git a/resources/src/main/java/org/robolectric/res/android/Chunk.java b/resources/src/main/java/org/robolectric/res/android/Chunk.java
index 131d0365c..823312cea 100644
--- a/resources/src/main/java/org/robolectric/res/android/Chunk.java
+++ b/resources/src/main/java/org/robolectric/res/android/Chunk.java
@@ -15,8 +15,8 @@ import org.robolectric.res.android.ResourceTypes.ResTable_type;
import org.robolectric.res.android.ResourceTypes.WithOffset;
// transliterated from
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/ChunkIterator.cpp and
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/include/androidfw/Chunk.h
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/ChunkIterator.cpp and
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/include/androidfw/Chunk.h
// Helpful wrapper around a ResChunk_header that provides getter methods
// that handle endianness conversions and provide access to the data portion
diff --git a/resources/src/main/java/org/robolectric/res/android/ConfigDescription.java b/resources/src/main/java/org/robolectric/res/android/ConfigDescription.java
index b3951601d..7bf419255 100644
--- a/resources/src/main/java/org/robolectric/res/android/ConfigDescription.java
+++ b/resources/src/main/java/org/robolectric/res/android/ConfigDescription.java
@@ -12,7 +12,7 @@ import java.util.regex.Pattern;
/**
* transliterated from
- * https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/tools/aapt2/ConfigDescription.cpp
+ * https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/tools/aapt2/ConfigDescription.cpp
*/
public class ConfigDescription {
public static final int SDK_CUPCAKE = 3;
@@ -525,14 +525,14 @@ public class ConfigDescription {
if (out != null) {
out.screenLayout2 =
(byte) ((out.screenLayout2 & ~ResTable_config.MASK_SCREENROUND) |
- ResTable_config.SCREENROUND_ANY);
+ ResTable_config.SCREENROUND_ANY);
}
return true;
} else if (Objects.equals(name, "round")) {
if (out != null) {
out.screenLayout2 =
(byte) ((out.screenLayout2 & ~ResTable_config.MASK_SCREENROUND) |
- ResTable_config.SCREENROUND_YES);
+ ResTable_config.SCREENROUND_YES);
}
return true;
} else if (Objects.equals(name, "notround")) {
@@ -551,19 +551,19 @@ public class ConfigDescription {
if (out != null)
out.colorMode =
(byte) ((out.colorMode & ~ResTable_config.MASK_WIDE_COLOR_GAMUT) |
- ResTable_config.WIDE_COLOR_GAMUT_ANY);
+ ResTable_config.WIDE_COLOR_GAMUT_ANY);
return true;
} else if (Objects.equals(name, "widecg")) {
if (out != null)
out.colorMode =
(byte) ((out.colorMode & ~ResTable_config.MASK_WIDE_COLOR_GAMUT) |
- ResTable_config.WIDE_COLOR_GAMUT_YES);
+ ResTable_config.WIDE_COLOR_GAMUT_YES);
return true;
} else if (Objects.equals(name, "nowidecg")) {
if (out != null)
out.colorMode =
(byte) ((out.colorMode & ~ResTable_config.MASK_WIDE_COLOR_GAMUT) |
- ResTable_config.WIDE_COLOR_GAMUT_NO);
+ ResTable_config.WIDE_COLOR_GAMUT_NO);
return true;
}
return false;
@@ -574,19 +574,19 @@ public class ConfigDescription {
if (out != null)
out.colorMode =
(byte) ((out.colorMode & ~ResTable_config.MASK_HDR) |
- ResTable_config.HDR_ANY);
+ ResTable_config.HDR_ANY);
return true;
} else if (Objects.equals(name, "highdr")) {
if (out != null)
out.colorMode =
(byte) ((out.colorMode & ~ResTable_config.MASK_HDR) |
- ResTable_config.HDR_YES);
+ ResTable_config.HDR_YES);
return true;
} else if (Objects.equals(name, "lowdr")) {
if (out != null)
out.colorMode =
(byte) ((out.colorMode & ~ResTable_config.MASK_HDR) |
- ResTable_config.HDR_NO);
+ ResTable_config.HDR_NO);
return true;
}
return false;
@@ -980,7 +980,7 @@ public class ConfigDescription {
return false;
}
- // transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/tools/aapt/AaptConfig.cpp
+ // transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/tools/aapt/AaptConfig.cpp
private static void applyVersionForCompatibility(ResTable_config config) {
if (config == null) {
return;
@@ -989,7 +989,7 @@ public class ConfigDescription {
if (((config.uiMode & ResTable_config.MASK_UI_MODE_TYPE)
== ResTable_config.UI_MODE_TYPE_VR_HEADSET) ||
(config.colorMode & ResTable_config.MASK_WIDE_COLOR_GAMUT) != 0 ||
- (config.colorMode & ResTable_config.MASK_HDR) != 0) {
+ (config.colorMode & ResTable_config.MASK_HDR) != 0) {
min_sdk = SDK_O;
} else if (isTruthy(config.screenLayout2 & ResTable_config.MASK_SCREENROUND)) {
min_sdk = SDK_MNC;
diff --git a/resources/src/main/java/org/robolectric/res/android/CppApkAssets.java b/resources/src/main/java/org/robolectric/res/android/CppApkAssets.java
index e9285d642..cbe6fa780 100644
--- a/resources/src/main/java/org/robolectric/res/android/CppApkAssets.java
+++ b/resources/src/main/java/org/robolectric/res/android/CppApkAssets.java
@@ -1,7 +1,7 @@
package org.robolectric.res.android;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/include/androidfw/ApkAssets.h
-// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/ApkAssets.cpp
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/include/androidfw/ApkAssets.h
+// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/ApkAssets.cpp
import static org.robolectric.res.android.CppAssetManager.FileType.kFileTypeDirectory;
import static org.robolectric.res.android.CppAssetManager.FileType.kFileTypeRegular;
@@ -253,9 +253,9 @@ public class CppApkAssets {
// Must retain ownership of the IDMAP Asset so that all pointers to its mmapped data remain valid.
loaded_apk.idmap_asset_ = idmap_asset;
- // const StringPiece data(
- // reinterpret_cast<const char*>(loaded_apk.resources_asset_.getBuffer(true /*wordAligned*/)),
- // loaded_apk.resources_asset_.getLength());
+ // const StringPiece data(
+ // reinterpret_cast<const char*>(loaded_apk.resources_asset_.getBuffer(true /*wordAligned*/)),
+ // loaded_apk.resources_asset_.getLength());
StringPiece data = new StringPiece(
ByteBuffer.wrap(loaded_apk.resources_asset_.getBuffer(true /*wordAligned*/))
.order(ByteOrder.LITTLE_ENDIAN),
diff --git a/resources/src/main/java/org/robolectric/res/android/CppAssetManager.java b/resources/src/main/java/org/robolectric/res/android/CppAssetManager.java
index 8633b889d..35f970b5b 100644
--- a/resources/src/main/java/org/robolectric/res/android/CppAssetManager.java
+++ b/resources/src/main/java/org/robolectric/res/android/CppAssetManager.java
@@ -33,7 +33,7 @@ import org.robolectric.res.android.AssetDir.FileInfo;
import org.robolectric.res.android.ZipFileRO.ZipEntryRO;
import org.robolectric.util.PerfStatsCollector;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/AssetManager.cpp
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/AssetManager.cpp
@SuppressWarnings("NewApi")
public class CppAssetManager {
@@ -117,9 +117,9 @@ public class CppAssetManager {
static final Asset kExcludedAsset = Asset.EXCLUDED_ASSET;
- static volatile int gCount = 0;
+ static volatile int gCount = 0;
-// final char* RESOURCES_FILENAME = "resources.arsc";
+ // final char* RESOURCES_FILENAME = "resources.arsc";
// final char* IDMAP_BIN = "/system/bin/idmap";
// final char* OVERLAY_DIR = "/vendor/overlay";
// final char* OVERLAY_THEME_DIR_PROPERTY = "ro.boot.vendor.overlay.theme";
@@ -838,7 +838,7 @@ public class CppAssetManager {
final asset_path ap) {
Asset pAsset = null;
- /* look at the filesystem on disk */
+ /* look at the filesystem on disk */
if (ap.type == kFileTypeDirectory) {
String8 path = new String8(ap.path);
path.appendPath(fileName);
@@ -846,7 +846,7 @@ public class CppAssetManager {
pAsset = openAssetFromFileLocked(path, mode);
if (pAsset == null) {
- /* try again, this time with ".gz" */
+ /* try again, this time with ".gz" */
path.append(".gz");
pAsset = openAssetFromFileLocked(path, mode);
}
@@ -860,7 +860,7 @@ public class CppAssetManager {
} else {
String8 path = new String8(fileName);
- /* check the appropriate Zip file */
+ /* check the appropriate Zip file */
ZipFileRO pZip = getZipFileLocked(ap);
if (pZip != null) {
//printf("GOT zip, checking NA '%s'\n", (final char*) path);
@@ -873,7 +873,7 @@ public class CppAssetManager {
}
if (pAsset != null) {
- /* create a "source" name, for debug/display */
+ /* create a "source" name, for debug/display */
pAsset.setAssetSource(
createZipSourceNameLocked(ap.path, new String8(), new String8(fileName)));
}
@@ -984,7 +984,7 @@ public class CppAssetManager {
pZipFile.mFileName, mode, pAsset);
}
if (pAsset == null) {
- /* unexpected */
+ /* unexpected */
ALOGW("create from segment failed\n");
}
@@ -1125,11 +1125,11 @@ public class CppAssetManager {
// if we wanted to do an incremental cache fill, we would do it here
- /*
- * Process "exclude" directives. If we find a filename that ends with
- * ".EXCLUDE", we look for a matching entry in the "merged" set, and
- * remove it if we find it. We also delete the "exclude" entry.
- */
+ /*
+ * Process "exclude" directives. If we find a filename that ends with
+ * ".EXCLUDE", we look for a matching entry in the "merged" set, and
+ * remove it if we find it. We also delete the "exclude" entry.
+ */
int i, count, exclExtLen;
count = pContents.size();
@@ -1256,7 +1256,7 @@ public class CppAssetManager {
zipName = ZipSet.getPathName(ap.path.string());
- /* convert "sounds" to "rootDir/sounds" */
+ /* convert "sounds" to "rootDir/sounds" */
if (rootDir != null) {
dirName = new String8(rootDir);
}
@@ -1351,9 +1351,9 @@ public class CppAssetManager {
pZip.endIteration(iterationCookie);
- /*
- * Add the set of unique directories.
- */
+ /*
+ * Add the set of unique directories.
+ */
for (int i = 0; i < dirs.size(); i++) {
AssetDir.FileInfo info = new FileInfo();
info.set(dirs.get(i), kFileTypeDirectory);
@@ -1379,26 +1379,26 @@ public class CppAssetManager {
*/
void mergeInfoLocked(Ref<SortedVector<AssetDir.FileInfo>> pMergedInfoRef,
final SortedVector<AssetDir.FileInfo> pContents) {
- /*
- * Merge what we found in this directory with what we found in
- * other places.
- *
- * Two basic approaches:
- * (1) Create a new array that holds the unique values of the two
- * arrays.
- * (2) Take the elements from pContents and shove them into pMergedInfo.
- *
- * Because these are vectors of complex objects, moving elements around
- * inside the vector requires finalructing new objects and allocating
- * storage for members. With approach #1, we're always adding to the
- * end, whereas with #2 we could be inserting multiple elements at the
- * front of the vector. Approach #1 requires a full copy of the
- * contents of pMergedInfo, but approach #2 requires the same copy for
- * every insertion at the front of pMergedInfo.
- *
- * (We should probably use a SortedVector interface that allows us to
- * just stuff items in, trusting us to maintain the sort order.)
- */
+ /*
+ * Merge what we found in this directory with what we found in
+ * other places.
+ *
+ * Two basic approaches:
+ * (1) Create a new array that holds the unique values of the two
+ * arrays.
+ * (2) Take the elements from pContents and shove them into pMergedInfo.
+ *
+ * Because these are vectors of complex objects, moving elements around
+ * inside the vector requires finalructing new objects and allocating
+ * storage for members. With approach #1, we're always adding to the
+ * end, whereas with #2 we could be inserting multiple elements at the
+ * front of the vector. Approach #1 requires a full copy of the
+ * contents of pMergedInfo, but approach #2 requires the same copy for
+ * every insertion at the front of pMergedInfo.
+ *
+ * (We should probably use a SortedVector interface that allows us to
+ * just stuff items in, trusting us to maintain the sort order.)
+ */
SortedVector<AssetDir.FileInfo> pNewSorted;
int mergeMax, contMax;
int mergeIdx, contIdx;
@@ -1411,33 +1411,33 @@ public class CppAssetManager {
while (mergeIdx < mergeMax || contIdx < contMax) {
if (mergeIdx == mergeMax) {
- /* hit end of "merge" list, copy rest of "contents" */
+ /* hit end of "merge" list, copy rest of "contents" */
pNewSorted.add(pContents.itemAt(contIdx));
contIdx++;
} else if (contIdx == contMax) {
- /* hit end of "cont" list, copy rest of "merge" */
+ /* hit end of "cont" list, copy rest of "merge" */
pNewSorted.add(pMergedInfo.itemAt(mergeIdx));
mergeIdx++;
} else if (pMergedInfo.itemAt(mergeIdx) == pContents.itemAt(contIdx)) {
- /* items are identical, add newer and advance both indices */
+ /* items are identical, add newer and advance both indices */
pNewSorted.add(pContents.itemAt(contIdx));
mergeIdx++;
contIdx++;
} else if (pMergedInfo.itemAt(mergeIdx).isLessThan(pContents.itemAt(contIdx))) {
- /* "merge" is lower, add that one */
+ /* "merge" is lower, add that one */
pNewSorted.add(pMergedInfo.itemAt(mergeIdx));
mergeIdx++;
} else {
- /* "cont" is lower, add that one */
+ /* "cont" is lower, add that one */
assert (pContents.itemAt(contIdx).isLessThan(pMergedInfo.itemAt(mergeIdx)));
pNewSorted.add(pContents.itemAt(contIdx));
contIdx++;
}
}
- /*
- * Overwrite the "merged" list with the new stuff.
- */
+ /*
+ * Overwrite the "merged" list with the new stuff.
+ */
pMergedInfoRef.set(pNewSorted);
// #if 0 // for Vector, rather than SortedVector
@@ -1606,22 +1606,22 @@ public class CppAssetManager {
/*
- * Manage a set of Zip files. For each file we need a pointer to the
- * ZipFile and a time_t with the file's modification date.
- *
- * We currently only have two zip files (current app, "common" app).
- * (This was originally written for 8, based on app/locale/vendor.)
- */
+ * Manage a set of Zip files. For each file we need a pointer to the
+ * ZipFile and a time_t with the file's modification date.
+ *
+ * We currently only have two zip files (current app, "common" app).
+ * (This was originally written for 8, based on app/locale/vendor.)
+ */
static class ZipSet {
final List<String> mZipPath = new ArrayList<>();
final List<SharedZip> mZipFile = new ArrayList<>();
- /*
- * ===========================================================================
- * ZipSet
- * ===========================================================================
- */
+ /*
+ * ===========================================================================
+ * ZipSet
+ * ===========================================================================
+ */
/*
* Destructor. Close any open archives.
@@ -1728,12 +1728,12 @@ public class CppAssetManager {
// return zip.getOverlay(idx, out);
// }
//
- /*
- * Compute the zip file's index.
- *
- * "appName", "locale", and "vendor" should be set to null to indicate the
- * default directory.
- */
+ /*
+ * Compute the zip file's index.
+ *
+ * "appName", "locale", and "vendor" should be set to null to indicate the
+ * default directory.
+ */
int getIndex(final String zip) {
final int N = mZipPath.size();
for (int i = 0; i < N; i++) {
diff --git a/resources/src/main/java/org/robolectric/res/android/CppAssetManager2.java b/resources/src/main/java/org/robolectric/res/android/CppAssetManager2.java
index c1ac70bd2..0802c6dc0 100644
--- a/resources/src/main/java/org/robolectric/res/android/CppAssetManager2.java
+++ b/resources/src/main/java/org/robolectric/res/android/CppAssetManager2.java
@@ -40,11 +40,11 @@ import org.robolectric.res.android.ResourceTypes.ResTable_map_entry;
import org.robolectric.res.android.ResourceTypes.ResTable_type;
import org.robolectric.res.android.ResourceTypes.Res_value;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/include/androidfw/AssetManager2.h
-// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/AssetManager2.cpp
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/include/androidfw/AssetManager2.h
+// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/AssetManager2.cpp
public class CppAssetManager2 {
// #define ATRACE_TAG ATRACE_TAG_RESOURCES
-//
+//
// #include "androidfw/AssetManager2.h"
//#include <array>
@@ -91,6 +91,14 @@ public class CppAssetManager2 {
entry.type_pool = type_pool;
return entry;
}
+
+ @Override
+ public String toString() {
+ return "Entry{" +
+ "key=" + key +
+ ", value=" + value +
+ '}';
+ }
};
// Denotes the configuration axis that this bag varies with.
@@ -783,7 +791,7 @@ public class CppAssetManager2 {
// out_name.type16 = entry.type_string_ref.string();
// out_name.type_len = out_name.type16 == null ? 0 : out_name.type16.length();
// if (out_name.type16 == null) {
- return false;
+ return false;
// }
}
@@ -794,7 +802,7 @@ public class CppAssetManager2 {
// out_name.entry16 = entry.entry_string_ref.string();
// out_name.entry_len = out_name.entry16 == null ? 0 : out_name.entry16.length();
// if (out_name.entry16 == null) {
- return false;
+ return false;
// }
}
return true;
@@ -962,10 +970,12 @@ public class CppAssetManager2 {
// final ResTable_map map_entry_end = map_entry + dtohl(map.count);
final ResTable_map_entry map = new ResTable_map_entry(entry.entry.myBuf(), entry.entry.myOffset());
int curOffset = map.myOffset() + map.size;
- ResTable_map map_entry =
- new ResTable_map(map.myBuf(), curOffset);
+ ResTable_map map_entry = null; // = new ResTable_map(map.myBuf(), curOffset);
final int map_entry_end =
curOffset + dtohl(map.count) * ResTable_map.SIZEOF;
+ if (curOffset < map_entry_end) {
+ map_entry = new ResTable_map(map.myBuf(), curOffset);
+ }
// Keep track of ids that have already been seen to prevent infinite loops caused by circular
// dependencies between bags
@@ -975,7 +985,7 @@ public class CppAssetManager2 {
if (parent_resid.get() == 0 || child_resids.contains(parent_resid.get())) {
// There is no parent or that a circular dependency exist, meaning there is nothing to
// inherit and we can do a simple copy of the entries in the map.
- final int entry_count = (map_entry_end - map_entry.myOffset()) / ResTable_map.SIZEOF;
+ final int entry_count = (map_entry_end - curOffset) / ResTable_map.SIZEOF;
// util.unique_cptr<ResolvedBag> new_bag{reinterpret_cast<ResolvedBag*>(
// malloc(sizeof(ResolvedBag) + (entry_count * sizeof(ResolvedBag.Entry))))};
ResolvedBag new_bag = new ResolvedBag();
@@ -1045,13 +1055,13 @@ public class CppAssetManager2 {
final ResolvedBag.Entry[] new_entry = new_bag.entries;
int newEntryIndex = 0;
- // const ResolvedBag::Entry* parent_entry = parent_bag->entries;
+ // const ResolvedBag::Entry* parent_entry = parent_bag->entries;
int parentEntryIndex = 0;
// final ResolvedBag.Entry parent_entry_end = parent_entry + parent_bag.entry_count;
final int parentEntryCount = parent_bag.entry_count;
// The keys are expected to be in sorted order. Merge the two bags.
- while (map_entry.myOffset() != map_entry_end && parentEntryIndex != parentEntryCount) {
+ while (map_entry != null && map_entry.myOffset() != map_entry_end && parentEntryIndex != parentEntryCount) {
final Ref<Integer> child_keyRef = new Ref<>(dtohl(map_entry.name.ident));
if (!is_internal_resid(child_keyRef.get())) {
if (entry.dynamic_ref_table.lookupResourceId(child_keyRef) != NO_ERROR) {
@@ -1106,7 +1116,7 @@ public class CppAssetManager2 {
}
// Finish the child entries if they exist.
- while (map_entry.myOffset() != map_entry_end) {
+ while (map_entry != null && map_entry.myOffset() != map_entry_end) {
final Ref<Integer> new_key = new Ref<>(map_entry.name.ident);
if (!is_internal_resid(new_key.get())) {
if (entry.dynamic_ref_table.lookupResourceId(new_key) != NO_ERROR) {
@@ -1170,6 +1180,15 @@ public class CppAssetManager2 {
return result2;
}
+ String GetResourceName(int resid) {
+ ResourceName out_name = new ResourceName();
+ if (GetResourceName(resid, out_name)) {
+ return out_name.package_ + ":" + out_name.type + "@" + out_name.entry;
+ } else {
+ return null;
+ }
+ }
+
static boolean Utf8ToUtf16(final String str, Ref<String> out) {
throw new UnsupportedOperationException();
// ssize_t len =
@@ -1260,12 +1279,13 @@ public class CppAssetManager2 {
//
// // Re-create it.
// new (impl.filtered_configs_) ByteBucketArray<FilteredConfigGroup>();
- impl.filtered_configs_ = new ByteBucketArray<FilteredConfigGroup>() {
- @Override
- FilteredConfigGroup newInstance() {
- return new FilteredConfigGroup();
- }
- };
+ impl.filtered_configs_ =
+ new ByteBucketArray<FilteredConfigGroup>(new FilteredConfigGroup()) {
+ @Override
+ FilteredConfigGroup newInstance() {
+ return new FilteredConfigGroup();
+ }
+ };
// Create the filters here.
impl.loaded_package_.ForEachTypeSpec((TypeSpec spec, byte type_index) -> {
diff --git a/resources/src/main/java/org/robolectric/res/android/DynamicRefTable.java b/resources/src/main/java/org/robolectric/res/android/DynamicRefTable.java
index 8836028b7..208075373 100644
--- a/resources/src/main/java/org/robolectric/res/android/DynamicRefTable.java
+++ b/resources/src/main/java/org/robolectric/res/android/DynamicRefTable.java
@@ -1,6 +1,6 @@
package org.robolectric.res.android;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/include/androidfw/ResourceTypes.h
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/include/androidfw/ResourceTypes.h
import static org.robolectric.res.android.Errors.NO_ERROR;
import static org.robolectric.res.android.Errors.UNKNOWN_ERROR;
@@ -92,7 +92,7 @@ public class DynamicRefTable
return NO_ERROR;
}
-// // Performs the actual conversion of build-time resource ID to run-time
+ // // Performs the actual conversion of build-time resource ID to run-time
// // resource ID.
int lookupResourceId(Ref<Integer> resId) {
int res = resId.get();
@@ -129,7 +129,7 @@ public class DynamicRefTable
resId.set((res & 0x00ffffff) | (((int) translatedId) << 24));
return NO_ERROR;
}
-//
+ //
int lookupResourceValue(Ref<Res_value> value) {
byte resolvedType = DataType.REFERENCE.code();
Res_value inValue = value.get();
@@ -163,7 +163,7 @@ public class DynamicRefTable
value.set(new Res_value(resolvedType, resIdRef.get()));
return NO_ERROR;
- }
+ }
public Map<String, Byte> entries() {
return mEntries;
@@ -175,7 +175,7 @@ public class DynamicRefTable
//}
//
// private:
- final byte mAssignedPackageId;
+ final byte mAssignedPackageId;
final byte[] mLookupTable = new byte[256];
final Map<String, Byte> mEntries = new HashMap<>();
boolean mAppAsLib;
diff --git a/resources/src/main/java/org/robolectric/res/android/Errors.java b/resources/src/main/java/org/robolectric/res/android/Errors.java
index 04fb8942c..0cab2b773 100644
--- a/resources/src/main/java/org/robolectric/res/android/Errors.java
+++ b/resources/src/main/java/org/robolectric/res/android/Errors.java
@@ -1,6 +1,6 @@
package org.robolectric.res.android;
-// transliterated from https://android.googlesource.com/platform/system/core/+/android-9.0.0_r3/include/utils/Errors.h
+// transliterated from https://android.googlesource.com/platform/system/core/+/android-9.0.0_r12/include/utils/Errors.h
public class Errors {
diff --git a/resources/src/main/java/org/robolectric/res/android/Idmap.java b/resources/src/main/java/org/robolectric/res/android/Idmap.java
index d71c25069..65a1e0d42 100644
--- a/resources/src/main/java/org/robolectric/res/android/Idmap.java
+++ b/resources/src/main/java/org/robolectric/res/android/Idmap.java
@@ -1,8 +1,8 @@
package org.robolectric.res.android;
// transliterated from
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/Idmap.cpp and
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/include/androidfw/Idmap.h
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/Idmap.cpp and
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/include/androidfw/Idmap.h
import static org.robolectric.res.android.Util.ATRACE_CALL;
import static org.robolectric.res.android.Util.SIZEOF_CPTR;
@@ -130,7 +130,7 @@ class Idmap {
// return true;
}
-// LoadedIdmap::LoadedIdmap(const Idmap_header* header) : header_(header) {
+ // LoadedIdmap::LoadedIdmap(const Idmap_header* header) : header_(header) {
// size_t length = strnlen(reinterpret_cast<const char*>(header_->overlay_path),
// arraysize(header_->overlay_path));
// overlay_apk_path_.assign(reinterpret_cast<const char*>(header_->overlay_path), length);
@@ -148,7 +148,7 @@ class Idmap {
// Can't use make_unique because LoadedImpl constructor is private.
LoadedIdmap loaded_idmap = new LoadedIdmap(header);
- // const byte* data_ptr = reinterpret_cast<const byte*>(idmap_data.data()) + sizeof(*header);
+ // const byte* data_ptr = reinterpret_cast<const byte*>(idmap_data.data()) + sizeof(*header);
StringPiece data_ptr = new StringPiece(idmap_data.myBuf(),
idmap_data.myOffset() + SIZEOF_CPTR);
// int data_size = idmap_data.size() - sizeof(*header);
@@ -162,7 +162,7 @@ class Idmap {
}
// Validate the type IDs.
- // IdmapEntry_header entry_header = reinterpret_cast<const IdmapEntry_header*>(data_ptr);
+ // IdmapEntry_header entry_header = reinterpret_cast<const IdmapEntry_header*>(data_ptr);
IdmapEntry_header entry_header = new IdmapEntry_header(data_ptr.myBuf(), data_ptr.myOffset());
if (!is_valid_type_id(dtohs(entry_header.target_type_id)) || !is_valid_type_id(dtohs(entry_header.overlay_type_id))) {
logError(String.format("Invalid type map (0x%02x -> 0x%02x)",
diff --git a/resources/src/main/java/org/robolectric/res/android/IdmapEntries.java b/resources/src/main/java/org/robolectric/res/android/IdmapEntries.java
index 5e394ecf1..0ea0d9a55 100644
--- a/resources/src/main/java/org/robolectric/res/android/IdmapEntries.java
+++ b/resources/src/main/java/org/robolectric/res/android/IdmapEntries.java
@@ -2,7 +2,7 @@ package org.robolectric.res.android;
import static org.robolectric.res.android.Errors.*;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/ResourceTypes.cpp
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/ResourceTypes.cpp
public class IdmapEntries {
public boolean hasEntries() {
diff --git a/resources/src/main/java/org/robolectric/res/android/LoadedArsc.java b/resources/src/main/java/org/robolectric/res/android/LoadedArsc.java
index 76a6a6762..3d3df2fa4 100644
--- a/resources/src/main/java/org/robolectric/res/android/LoadedArsc.java
+++ b/resources/src/main/java/org/robolectric/res/android/LoadedArsc.java
@@ -39,8 +39,8 @@ import org.robolectric.res.android.ResourceTypes.ResTable_type;
import org.robolectric.res.android.ResourceTypes.ResTable_typeSpec;
import org.robolectric.res.android.ResourceTypes.Res_value;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/include/androidfw/LoadedArsc.h
-// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/LoadedArsc.cpp
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/include/androidfw/LoadedArsc.h
+// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/LoadedArsc.cpp
public class LoadedArsc {
//#ifndef LOADEDARSC_H_
@@ -79,7 +79,7 @@ public class LoadedArsc {
static class TypeSpec {
public static final int SIZEOF = ResTable_typeSpec.SIZEOF + IdmapEntry_header.SIZEOF;
-
+
// Pointer to the mmapped data where flags are kept.
// Flags denote whether the resource entry is public
// and under which configurations it varies.
@@ -205,7 +205,7 @@ public class LoadedArsc {
// memcpy(type_spec + 1, types_.data(), types_.size() * sizeof(ElementType));
for (int i = 0; i < type_spec.types.length; i++) {
type_spec.types[i] = types_.get(i);
-
+
}
return type_spec;
}
@@ -730,7 +730,7 @@ public class LoadedArsc {
String package_name =
Util.ReadUtf16StringFromDevice(entry_iter.packageName,
entry_iter.packageName.length);
-
+
if (dtohl(entry_iter.packageId) >= 255) {
logError(String.format(
"Package ID %02x in RES_TABLE_LIBRARY_TYPE too large for package '%s'.",
@@ -837,7 +837,7 @@ public class LoadedArsc {
}
void ForEachTypeSpec(TypeSpecFunc f) {
- for (int i = 0; i < type_specs_.size(); i++) {
+ for (Integer i : type_specs_.keySet()) {
TypeSpec ptr = type_specs_.get(i);
if (ptr != null) {
byte type_id = ptr.type_spec.id;
diff --git a/resources/src/main/java/org/robolectric/res/android/LocaleData.java b/resources/src/main/java/org/robolectric/res/android/LocaleData.java
index 6d0d96287..0fe00f5da 100644
--- a/resources/src/main/java/org/robolectric/res/android/LocaleData.java
+++ b/resources/src/main/java/org/robolectric/res/android/LocaleData.java
@@ -9,7 +9,7 @@ import static org.robolectric.res.android.LocaleDataTables.SCRIPT_PARENTS;
import java.util.Arrays;
import java.util.Map;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/LocaleData.cpp
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/LocaleData.cpp
public class LocaleData {
private static int packLocale(final byte[] language, final byte[] region) {
diff --git a/resources/src/main/java/org/robolectric/res/android/LocaleDataTables.java b/resources/src/main/java/org/robolectric/res/android/LocaleDataTables.java
index a08e888cb..2cbfce281 100644
--- a/resources/src/main/java/org/robolectric/res/android/LocaleDataTables.java
+++ b/resources/src/main/java/org/robolectric/res/android/LocaleDataTables.java
@@ -6,100 +6,100 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/LocaleDataTables.cpp
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/LocaleDataTables.cpp
public class LocaleDataTables {
// Auto-generated by ./tools/localedata/extract_icu_data.py
static final byte[][] SCRIPT_CODES = {
- /* 0 */ {'A', 'h', 'o', 'm'},
- /* 1 */ {'A', 'r', 'a', 'b'},
- /* 2 */ {'A', 'r', 'm', 'i'},
- /* 3 */ {'A', 'r', 'm', 'n'},
- /* 4 */ {'A', 'v', 's', 't'},
- /* 5 */ {'B', 'a', 'm', 'u'},
- /* 6 */ {'B', 'a', 's', 's'},
- /* 7 */ {'B', 'e', 'n', 'g'},
- /* 8 */ {'B', 'r', 'a', 'h'},
- /* 9 */ {'C', 'a', 'n', 's'},
- /* 10 */ {'C', 'a', 'r', 'i'},
- /* 11 */ {'C', 'h', 'a', 'm'},
- /* 12 */ {'C', 'h', 'e', 'r'},
- /* 13 */ {'C', 'o', 'p', 't'},
- /* 14 */ {'C', 'p', 'r', 't'},
- /* 15 */ {'C', 'y', 'r', 'l'},
- /* 16 */ {'D', 'e', 'v', 'a'},
- /* 17 */ {'E', 'g', 'y', 'p'},
- /* 18 */ {'E', 't', 'h', 'i'},
- /* 19 */ {'G', 'e', 'o', 'r'},
- /* 20 */ {'G', 'o', 't', 'h'},
- /* 21 */ {'G', 'r', 'e', 'k'},
- /* 22 */ {'G', 'u', 'j', 'r'},
- /* 23 */ {'G', 'u', 'r', 'u'},
- /* 24 */ {'H', 'a', 'n', 's'},
- /* 25 */ {'H', 'a', 'n', 't'},
- /* 26 */ {'H', 'a', 't', 'r'},
- /* 27 */ {'H', 'e', 'b', 'r'},
- /* 28 */ {'H', 'l', 'u', 'w'},
- /* 29 */ {'H', 'm', 'n', 'g'},
- /* 30 */ {'I', 't', 'a', 'l'},
- /* 31 */ {'J', 'p', 'a', 'n'},
- /* 32 */ {'K', 'a', 'l', 'i'},
- /* 33 */ {'K', 'a', 'n', 'a'},
- /* 34 */ {'K', 'h', 'a', 'r'},
- /* 35 */ {'K', 'h', 'm', 'r'},
- /* 36 */ {'K', 'n', 'd', 'a'},
- /* 37 */ {'K', 'o', 'r', 'e'},
- /* 38 */ {'L', 'a', 'n', 'a'},
- /* 39 */ {'L', 'a', 'o', 'o'},
- /* 40 */ {'L', 'a', 't', 'n'},
- /* 41 */ {'L', 'e', 'p', 'c'},
- /* 42 */ {'L', 'i', 'n', 'a'},
- /* 43 */ {'L', 'i', 's', 'u'},
- /* 44 */ {'L', 'y', 'c', 'i'},
- /* 45 */ {'L', 'y', 'd', 'i'},
- /* 46 */ {'M', 'a', 'n', 'd'},
- /* 47 */ {'M', 'a', 'n', 'i'},
- /* 48 */ {'M', 'e', 'r', 'c'},
- /* 49 */ {'M', 'l', 'y', 'm'},
- /* 50 */ {'M', 'o', 'n', 'g'},
- /* 51 */ {'M', 'r', 'o', 'o'},
- /* 52 */ {'M', 'y', 'm', 'r'},
- /* 53 */ {'N', 'a', 'r', 'b'},
- /* 54 */ {'N', 'k', 'o', 'o'},
- /* 55 */ {'O', 'g', 'a', 'm'},
- /* 56 */ {'O', 'r', 'k', 'h'},
- /* 57 */ {'O', 'r', 'y', 'a'},
- /* 58 */ {'O', 's', 'g', 'e'},
- /* 59 */ {'P', 'a', 'u', 'c'},
- /* 60 */ {'P', 'h', 'l', 'i'},
- /* 61 */ {'P', 'h', 'n', 'x'},
- /* 62 */ {'P', 'l', 'r', 'd'},
- /* 63 */ {'P', 'r', 't', 'i'},
- /* 64 */ {'R', 'u', 'n', 'r'},
- /* 65 */ {'S', 'a', 'm', 'r'},
- /* 66 */ {'S', 'a', 'r', 'b'},
- /* 67 */ {'S', 'a', 'u', 'r'},
- /* 68 */ {'S', 'g', 'n', 'w'},
- /* 69 */ {'S', 'i', 'n', 'h'},
- /* 70 */ {'S', 'o', 'r', 'a'},
- /* 71 */ {'S', 'y', 'r', 'c'},
- /* 72 */ {'T', 'a', 'l', 'e'},
- /* 73 */ {'T', 'a', 'l', 'u'},
- /* 74 */ {'T', 'a', 'm', 'l'},
- /* 75 */ {'T', 'a', 'n', 'g'},
- /* 76 */ {'T', 'a', 'v', 't'},
- /* 77 */ {'T', 'e', 'l', 'u'},
- /* 78 */ {'T', 'f', 'n', 'g'},
- /* 79 */ {'T', 'h', 'a', 'a'},
- /* 80 */ {'T', 'h', 'a', 'i'},
- /* 81 */ {'T', 'i', 'b', 't'},
- /* 82 */ {'U', 'g', 'a', 'r'},
- /* 83 */ {'V', 'a', 'i', 'i'},
- /* 84 */ {'X', 'p', 'e', 'o'},
- /* 85 */ {'X', 's', 'u', 'x'},
- /* 86 */ {'Y', 'i', 'i', 'i'},
- /* 87 */ {'~', '~', '~', 'A'},
- /* 88 */ {'~', '~', '~', 'B'},
+ /* 0 */ {'A', 'h', 'o', 'm'},
+ /* 1 */ {'A', 'r', 'a', 'b'},
+ /* 2 */ {'A', 'r', 'm', 'i'},
+ /* 3 */ {'A', 'r', 'm', 'n'},
+ /* 4 */ {'A', 'v', 's', 't'},
+ /* 5 */ {'B', 'a', 'm', 'u'},
+ /* 6 */ {'B', 'a', 's', 's'},
+ /* 7 */ {'B', 'e', 'n', 'g'},
+ /* 8 */ {'B', 'r', 'a', 'h'},
+ /* 9 */ {'C', 'a', 'n', 's'},
+ /* 10 */ {'C', 'a', 'r', 'i'},
+ /* 11 */ {'C', 'h', 'a', 'm'},
+ /* 12 */ {'C', 'h', 'e', 'r'},
+ /* 13 */ {'C', 'o', 'p', 't'},
+ /* 14 */ {'C', 'p', 'r', 't'},
+ /* 15 */ {'C', 'y', 'r', 'l'},
+ /* 16 */ {'D', 'e', 'v', 'a'},
+ /* 17 */ {'E', 'g', 'y', 'p'},
+ /* 18 */ {'E', 't', 'h', 'i'},
+ /* 19 */ {'G', 'e', 'o', 'r'},
+ /* 20 */ {'G', 'o', 't', 'h'},
+ /* 21 */ {'G', 'r', 'e', 'k'},
+ /* 22 */ {'G', 'u', 'j', 'r'},
+ /* 23 */ {'G', 'u', 'r', 'u'},
+ /* 24 */ {'H', 'a', 'n', 's'},
+ /* 25 */ {'H', 'a', 'n', 't'},
+ /* 26 */ {'H', 'a', 't', 'r'},
+ /* 27 */ {'H', 'e', 'b', 'r'},
+ /* 28 */ {'H', 'l', 'u', 'w'},
+ /* 29 */ {'H', 'm', 'n', 'g'},
+ /* 30 */ {'I', 't', 'a', 'l'},
+ /* 31 */ {'J', 'p', 'a', 'n'},
+ /* 32 */ {'K', 'a', 'l', 'i'},
+ /* 33 */ {'K', 'a', 'n', 'a'},
+ /* 34 */ {'K', 'h', 'a', 'r'},
+ /* 35 */ {'K', 'h', 'm', 'r'},
+ /* 36 */ {'K', 'n', 'd', 'a'},
+ /* 37 */ {'K', 'o', 'r', 'e'},
+ /* 38 */ {'L', 'a', 'n', 'a'},
+ /* 39 */ {'L', 'a', 'o', 'o'},
+ /* 40 */ {'L', 'a', 't', 'n'},
+ /* 41 */ {'L', 'e', 'p', 'c'},
+ /* 42 */ {'L', 'i', 'n', 'a'},
+ /* 43 */ {'L', 'i', 's', 'u'},
+ /* 44 */ {'L', 'y', 'c', 'i'},
+ /* 45 */ {'L', 'y', 'd', 'i'},
+ /* 46 */ {'M', 'a', 'n', 'd'},
+ /* 47 */ {'M', 'a', 'n', 'i'},
+ /* 48 */ {'M', 'e', 'r', 'c'},
+ /* 49 */ {'M', 'l', 'y', 'm'},
+ /* 50 */ {'M', 'o', 'n', 'g'},
+ /* 51 */ {'M', 'r', 'o', 'o'},
+ /* 52 */ {'M', 'y', 'm', 'r'},
+ /* 53 */ {'N', 'a', 'r', 'b'},
+ /* 54 */ {'N', 'k', 'o', 'o'},
+ /* 55 */ {'O', 'g', 'a', 'm'},
+ /* 56 */ {'O', 'r', 'k', 'h'},
+ /* 57 */ {'O', 'r', 'y', 'a'},
+ /* 58 */ {'O', 's', 'g', 'e'},
+ /* 59 */ {'P', 'a', 'u', 'c'},
+ /* 60 */ {'P', 'h', 'l', 'i'},
+ /* 61 */ {'P', 'h', 'n', 'x'},
+ /* 62 */ {'P', 'l', 'r', 'd'},
+ /* 63 */ {'P', 'r', 't', 'i'},
+ /* 64 */ {'R', 'u', 'n', 'r'},
+ /* 65 */ {'S', 'a', 'm', 'r'},
+ /* 66 */ {'S', 'a', 'r', 'b'},
+ /* 67 */ {'S', 'a', 'u', 'r'},
+ /* 68 */ {'S', 'g', 'n', 'w'},
+ /* 69 */ {'S', 'i', 'n', 'h'},
+ /* 70 */ {'S', 'o', 'r', 'a'},
+ /* 71 */ {'S', 'y', 'r', 'c'},
+ /* 72 */ {'T', 'a', 'l', 'e'},
+ /* 73 */ {'T', 'a', 'l', 'u'},
+ /* 74 */ {'T', 'a', 'm', 'l'},
+ /* 75 */ {'T', 'a', 'n', 'g'},
+ /* 76 */ {'T', 'a', 'v', 't'},
+ /* 77 */ {'T', 'e', 'l', 'u'},
+ /* 78 */ {'T', 'f', 'n', 'g'},
+ /* 79 */ {'T', 'h', 'a', 'a'},
+ /* 80 */ {'T', 'h', 'a', 'i'},
+ /* 81 */ {'T', 'i', 'b', 't'},
+ /* 82 */ {'U', 'g', 'a', 'r'},
+ /* 83 */ {'V', 'a', 'i', 'i'},
+ /* 84 */ {'X', 'p', 'e', 'o'},
+ /* 85 */ {'X', 's', 'u', 'x'},
+ /* 86 */ {'Y', 'i', 'i', 'i'},
+ /* 87 */ {'~', '~', '~', 'A'},
+ /* 88 */ {'~', '~', '~', 'B'},
};
static final Map<Integer, Byte> LIKELY_SCRIPTS;
diff --git a/resources/src/main/java/org/robolectric/res/android/ResStringPool.java b/resources/src/main/java/org/robolectric/res/android/ResStringPool.java
index d08f5dd98..7180a3328 100644
--- a/resources/src/main/java/org/robolectric/res/android/ResStringPool.java
+++ b/resources/src/main/java/org/robolectric/res/android/ResStringPool.java
@@ -1,7 +1,7 @@
package org.robolectric.res.android;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/ResourceTypes.cpp
-// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/include/androidfw/ResourceTypes.h
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/ResourceTypes.cpp
+// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/include/androidfw/ResourceTypes.h
import static org.robolectric.res.android.Errors.BAD_TYPE;
import static org.robolectric.res.android.Errors.NAME_NOT_FOUND;
@@ -38,25 +38,25 @@ public class ResStringPool {
private int mError;
- byte[] mOwnedData;
+ byte[] mOwnedData;
//private Object mOwnedData;
private ResStringPool_header mHeader;
private int mSize;
-// private mutable Mutex mDecodeLock;
+ // private mutable Mutex mDecodeLock;
// const uint32_t* mEntries;
private IntArray mEntries;
-// const uint32_t* mEntryStyles;
- private IntArray mEntryStyles;
-// const void* mStrings;
- private int mStrings;
+ // const uint32_t* mEntryStyles;
+ private IntArray mEntryStyles;
+ // const void* mStrings;
+ private int mStrings;
//private List<String> mStrings;
//private String[] mCache;
//private char16_t mutable** mCache;
- private int mStringPoolSize; // number of uint16_t
-// const uint32_t* mStyles;
- private int mStyles;
- private int mStylePoolSize; // number of int
+ private int mStringPoolSize; // number of uint16_t
+ // const uint32_t* mStyles;
+ private int mStyles;
+ private int mStylePoolSize; // number of int
public ResStringPool() {
mError = NO_INIT;
@@ -242,8 +242,8 @@ public class ResStringPool {
if (isTruthy(mHeader.flags&ResStringPool_header.UTF8_FLAG) &&
(mHeader.getByte(mStrings + mStringPoolSize-1) != 0) ||
- (!isTruthy(mHeader.flags&ResStringPool_header.UTF8_FLAG) &&
- ((mHeader.getShort(mStrings + mStringPoolSize*2-2) != 0)))) {
+ (!isTruthy(mHeader.flags&ResStringPool_header.UTF8_FLAG) &&
+ ((mHeader.getShort(mStrings + mStringPoolSize*2-2) != 0)))) {
ALOGW("Bad string block: last string is not 0-terminated\n");
return (mError=BAD_TYPE);
}
@@ -264,7 +264,7 @@ public class ResStringPool {
if ((mEntryStyles.myOffset() - mHeader.myOffset()) > (int)size) {
ALOGW("Bad string block: entry of %d styles extends past data size %d\n",
(int)(mEntryStyles.myOffset()),
- (int)size);
+ (int)size);
return (mError=BAD_TYPE);
}
mStyles = mHeader.stylesStart;
@@ -327,13 +327,13 @@ public class ResStringPool {
public String stringAt(int idx) {
if (mError == NO_ERROR && idx < mHeader.stringCount) {
- final boolean isUTF8 = (mHeader.flags&ResStringPool_header.UTF8_FLAG) != 0;
+ final boolean isUTF8 = (mHeader.flags&ResStringPool_header.UTF8_FLAG) != 0;
// const uint32_t off = mEntries[idx]/(isUTF8?sizeof(uint8_t):sizeof(uint16_t));
ByteBuffer buf = mHeader.myBuf();
int bufOffset = mHeader.myOffset();
// const uint32_t off = mEntries[idx]/(isUTF8?sizeof(uint8_t):sizeof(uint16_t));
final int off = mEntries.get(idx)
- /(isUTF8?1/*sizeof(uint8_t)*/:2/*sizeof(uint16_t)*/);
+ /(isUTF8?1/*sizeof(uint8_t)*/:2/*sizeof(uint16_t)*/);
if (off < (mStringPoolSize-1)) {
if (!isUTF8) {
final int strings = mStrings;
@@ -535,18 +535,18 @@ public class ResStringPool {
return NAME_NOT_FOUND;
}
-//
- public int size() {
- return mError == NO_ERROR ? mHeader.stringCount : 0;
- }
+ //
+ public int size() {
+ return mError == NO_ERROR ? mHeader.stringCount : 0;
+ }
- int styleCount() {
- return mError == NO_ERROR ? mHeader.styleCount : 0;
- }
+ int styleCount() {
+ return mError == NO_ERROR ? mHeader.styleCount : 0;
+ }
- int bytes() {
- return mError == NO_ERROR ? mHeader.header.size : 0;
- }
+ int bytes() {
+ return mError == NO_ERROR ? mHeader.header.size : 0;
+ }
public boolean isUTF8() {
return true;
diff --git a/resources/src/main/java/org/robolectric/res/android/ResStringPoolHeader.java b/resources/src/main/java/org/robolectric/res/android/ResStringPoolHeader.java
index 30eb7b1b4..308ab6843 100644
--- a/resources/src/main/java/org/robolectric/res/android/ResStringPoolHeader.java
+++ b/resources/src/main/java/org/robolectric/res/android/ResStringPoolHeader.java
@@ -17,7 +17,7 @@ import org.robolectric.res.android.ResourceTypes.ResChunk_header;
* into a style table starting at stylesStart. Each entry in the
* style table is an array of ResStringPool_span structures.
*/
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/include/androidfw/ResourceTypes.h#434
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/include/androidfw/ResourceTypes.h#434
public class ResStringPoolHeader {
public static final int SIZEOF = ResChunk_header.SIZEOF + 20;
diff --git a/resources/src/main/java/org/robolectric/res/android/ResTable.java b/resources/src/main/java/org/robolectric/res/android/ResTable.java
index f94c00bad..24e232684 100644
--- a/resources/src/main/java/org/robolectric/res/android/ResTable.java
+++ b/resources/src/main/java/org/robolectric/res/android/ResTable.java
@@ -46,8 +46,8 @@ import org.robolectric.res.android.ResourceTypes.ResTable_type;
import org.robolectric.res.android.ResourceTypes.ResTable_typeSpec;
import org.robolectric.res.android.ResourceTypes.Res_value;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/ResourceTypes.cpp
-// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/include/androidfw/ResourceTypes.h
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/ResourceTypes.cpp
+// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/include/androidfw/ResourceTypes.h
@SuppressWarnings("NewApi")
public class ResTable {
@@ -140,7 +140,7 @@ public class ResTable {
// copyData);
// }
-// status_t add(Asset* asset, Asset* idmapAsset, const int32_t cookie=-1, bool copyData=false,
+ // status_t add(Asset* asset, Asset* idmapAsset, const int32_t cookie=-1, bool copyData=false,
// bool appAsLib=false, bool isSystemAsset=false);
int add(
Asset asset, Asset idmapAsset, final int cookie, boolean copyData,
@@ -216,7 +216,7 @@ public class ResTable {
return (mError=NO_ERROR);
}
-// status_t addInternal(const void* data, size_t size, const void* idmapData, size_t idmapDataSize,
+ // status_t addInternal(const void* data, size_t size, const void* idmapData, size_t idmapDataSize,
// bool appAsLib, const int32_t cookie, bool copyData, bool isSystemAsset=false);
int addInternal(byte[] data, int dataSize, final Object idmapData, int idmapDataSize,
boolean appAsLib, final int cookie, boolean copyData, boolean isSystemAsset)
@@ -295,52 +295,52 @@ public class ResTable {
// (const ResChunk_header*)(((const uint8_t*)header->header)
// + dtohs(header->header->header.headerSize));
ResChunk_header chunk =
- new ResChunk_header(buf, dtohs(header.header.header.headerSize));
+ new ResChunk_header(buf, dtohs(header.header.header.headerSize));
while (chunk != null && (chunk.myOffset()) <= (header.dataEnd -ResChunk_header.SIZEOF) &&
- (chunk.myOffset()) <= (header.dataEnd -dtohl(chunk.size))) {
- int err = validate_chunk(chunk, ResChunk_header.SIZEOF, header.dataEnd, "ResTable");
- if (err != NO_ERROR) {
- return (mError=err);
- }
- if (kDebugTableNoisy) {
- ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%s\n",
- dtohs(chunk.type), dtohs(chunk.headerSize), dtohl(chunk.size),
- (Object)((chunk.myOffset()) - (header.header.myOffset())));
- }
- final int csize = dtohl(chunk.size);
- final int ctype = dtohs(chunk.type);
- if (ctype == RES_STRING_POOL_TYPE) {
- if (header.values.getError() != NO_ERROR) {
- // Only use the first string chunk; ignore any others that
- // may appear.
- err = header.values.setTo(chunk.myBuf(), chunk.myOffset(), csize, false);
- if (err != NO_ERROR) {
- return (mError=err);
- }
- } else {
- ALOGW("Multiple string chunks found in resource table.");
+ (chunk.myOffset()) <= (header.dataEnd -dtohl(chunk.size))) {
+ int err = validate_chunk(chunk, ResChunk_header.SIZEOF, header.dataEnd, "ResTable");
+ if (err != NO_ERROR) {
+ return (mError=err);
}
- } else if (ctype == RES_TABLE_PACKAGE_TYPE) {
- if (curPackage >= dtohl(header.header.packageCount)) {
- ALOGW("More package chunks were found than the %d declared in the header.",
- dtohl(header.header.packageCount));
- return (mError=BAD_TYPE);
+ if (kDebugTableNoisy) {
+ ALOGV("Chunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%s\n",
+ dtohs(chunk.type), dtohs(chunk.headerSize), dtohl(chunk.size),
+ (Object)((chunk.myOffset()) - (header.header.myOffset())));
}
+ final int csize = dtohl(chunk.size);
+ final int ctype = dtohs(chunk.type);
+ if (ctype == RES_STRING_POOL_TYPE) {
+ if (header.values.getError() != NO_ERROR) {
+ // Only use the first string chunk; ignore any others that
+ // may appear.
+ err = header.values.setTo(chunk.myBuf(), chunk.myOffset(), csize, false);
+ if (err != NO_ERROR) {
+ return (mError=err);
+ }
+ } else {
+ ALOGW("Multiple string chunks found in resource table.");
+ }
+ } else if (ctype == RES_TABLE_PACKAGE_TYPE) {
+ if (curPackage >= dtohl(header.header.packageCount)) {
+ ALOGW("More package chunks were found than the %d declared in the header.",
+ dtohl(header.header.packageCount));
+ return (mError=BAD_TYPE);
+ }
- if (parsePackage(
- new ResTable_package(chunk.myBuf(), chunk.myOffset()), header, appAsLib, isSystemAsset) != NO_ERROR) {
- return mError;
+ if (parsePackage(
+ new ResTable_package(chunk.myBuf(), chunk.myOffset()), header, appAsLib, isSystemAsset) != NO_ERROR) {
+ return mError;
+ }
+ curPackage++;
+ } else {
+ ALOGW("Unknown chunk type 0x%x in table at 0x%x.\n",
+ ctype,
+ (chunk.myOffset()) - (header.header.myOffset()));
}
- curPackage++;
- } else {
- ALOGW("Unknown chunk type 0x%x in table at 0x%x.\n",
- ctype,
- (chunk.myOffset()) - (header.header.myOffset()));
+ chunk = chunk.myOffset() + csize < header.dataEnd
+ ? new ResChunk_header(chunk.myBuf(), chunk.myOffset() + csize)
+ : null;
}
- chunk = chunk.myOffset() + csize < header.dataEnd
- ? new ResChunk_header(chunk.myBuf(), chunk.myOffset() + csize)
- : null;
- }
if (curPackage < dtohl(header.header.packageCount)) {
ALOGW("Fewer package chunks (%d) were found than the %d declared in the header.",
@@ -436,10 +436,10 @@ public class ResTable {
// }
if (outSpecFlags != null) {
- outSpecFlags.set(entry.specFlags);
+ outSpecFlags.set(entry.specFlags);
}
if (outConfig != null) {
- outConfig.set(entry.config);
+ outConfig.set(entry.config);
}
return entry._package_.header.index;
}
@@ -495,8 +495,8 @@ public class ResTable {
}
ResTable_sparseTypeEntry lower_bound(ResTable_sparseTypeEntry first, ResTable_sparseTypeEntry last,
- ResTable_sparseTypeEntry value,
- Compare comparator) {
+ ResTable_sparseTypeEntry value,
+ Compare comparator) {
int count = (last.myOffset() - first.myOffset()) / ResTable_sparseTypeEntry.SIZEOF;
int itOffset;
int step;
@@ -705,7 +705,7 @@ public class ResTable {
ALOGW("ResTable_entry size 0x%x is too small", dtohs(entry.size));
return BAD_TYPE;
}
-
+
if (outEntry != null) {
outEntry.entry = entry;
outEntry.config = bestConfig;
@@ -719,11 +719,11 @@ public class ResTable {
}
int parsePackage(ResTable_package pkg,
- Header header, boolean appAsLib, boolean isSystemAsset)
+ Header header, boolean appAsLib, boolean isSystemAsset)
{
int base = pkg.myOffset();
int err = validate_chunk(pkg.header, ResTable_package.SIZEOF - 4 /*sizeof(pkg.typeIdOffset)*/,
- header.dataEnd, "ResTable_package");
+ header.dataEnd, "ResTable_package");
if (err != NO_ERROR) {
return (mError=err);
}
@@ -778,13 +778,13 @@ public class ResTable {
PackageGroup group = null;
Package _package = new Package(this, header, pkg);
if (_package == NULL) {
- return (mError=NO_MEMORY);
- }
+ return (mError=NO_MEMORY);
+ }
// err = package->typeStrings.setTo(base+dtohl(pkg->typeStrings),
// header->dataEnd-(base+dtohl(pkg->typeStrings)));
err = _package.typeStrings.setTo(pkg.myBuf(), base+dtohl(pkg.typeStrings),
- header.dataEnd -(base+dtohl(pkg.typeStrings)), false);
+ header.dataEnd -(base+dtohl(pkg.typeStrings)), false);
if (err != NO_ERROR) {
// delete group;
// delete _package;
@@ -794,7 +794,7 @@ public class ResTable {
// err = package->keyStrings.setTo(base+dtohl(pkg->keyStrings),
// header->dataEnd-(base+dtohl(pkg->keyStrings)));
err = _package.keyStrings.setTo(pkg.myBuf(), base+dtohl(pkg.keyStrings),
- header.dataEnd -(base+dtohl(pkg.keyStrings)), false);
+ header.dataEnd -(base+dtohl(pkg.keyStrings)), false);
if (err != NO_ERROR) {
// delete group;
// delete _package;
@@ -841,177 +841,177 @@ public class ResTable {
// Iterate through all chunks.
ResChunk_header chunk =
- new ResChunk_header(pkg.myBuf(), pkg.myOffset() + dtohs(pkg.header.headerSize));
+ new ResChunk_header(pkg.myBuf(), pkg.myOffset() + dtohs(pkg.header.headerSize));
// const uint8_t* endPos = ((const uint8_t*)pkg) + dtohs(pkg->header.size);
final int endPos = (pkg.myOffset()) + pkg.header.size;
// while (((const uint8_t*)chunk) <= (endPos-sizeof(ResChunk_header)) &&
// ((const uint8_t*)chunk) <= (endPos-dtohl(chunk->size))) {
while (chunk != null && (chunk.myOffset()) <= (endPos-ResChunk_header.SIZEOF) &&
- (chunk.myOffset()) <= (endPos-dtohl(chunk.size))) {
- if (kDebugTableNoisy) {
- ALOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%s\n",
- dtohs(chunk.type), dtohs(chunk.headerSize), dtohl(chunk.size),
- ((chunk.myOffset()) - (header.header.myOffset())));
- }
- final int csize = dtohl(chunk.size);
- final short ctype = dtohs(chunk.type);
- if (ctype == RES_TABLE_TYPE_SPEC_TYPE) {
- final ResTable_typeSpec typeSpec = new ResTable_typeSpec(chunk.myBuf(), chunk.myOffset());
- err = validate_chunk(typeSpec.header, ResTable_typeSpec.SIZEOF,
- endPos, "ResTable_typeSpec");
- if (err != NO_ERROR) {
- return (mError=err);
+ (chunk.myOffset()) <= (endPos-dtohl(chunk.size))) {
+ if (kDebugTableNoisy) {
+ ALOGV("PackageChunk: type=0x%x, headerSize=0x%x, size=0x%x, pos=%s\n",
+ dtohs(chunk.type), dtohs(chunk.headerSize), dtohl(chunk.size),
+ ((chunk.myOffset()) - (header.header.myOffset())));
}
+ final int csize = dtohl(chunk.size);
+ final short ctype = dtohs(chunk.type);
+ if (ctype == RES_TABLE_TYPE_SPEC_TYPE) {
+ final ResTable_typeSpec typeSpec = new ResTable_typeSpec(chunk.myBuf(), chunk.myOffset());
+ err = validate_chunk(typeSpec.header, ResTable_typeSpec.SIZEOF,
+ endPos, "ResTable_typeSpec");
+ if (err != NO_ERROR) {
+ return (mError=err);
+ }
- final int typeSpecSize = dtohl(typeSpec.header.size);
- final int newEntryCount = dtohl(typeSpec.entryCount);
-
- if (kDebugLoadTableNoisy) {
- ALOGI("TypeSpec off %s: type=0x%x, headerSize=0x%x, size=%s\n",
- (base-chunk.myOffset()),
- dtohs(typeSpec.header.type),
- dtohs(typeSpec.header.headerSize),
- typeSpecSize);
- }
- // look for block overrun or int overflow when multiplying by 4
- if ((dtohl(typeSpec.entryCount) > (Integer.MAX_VALUE/4 /*sizeof(int)*/)
- || dtohs(typeSpec.header.headerSize)+(4 /*sizeof(int)*/*newEntryCount)
- > typeSpecSize)) {
- ALOGW("ResTable_typeSpec entry index to %s extends beyond chunk end %s.",
- (dtohs(typeSpec.header.headerSize) + (4 /*sizeof(int)*/*newEntryCount)),
- typeSpecSize);
- return (mError=BAD_TYPE);
- }
+ final int typeSpecSize = dtohl(typeSpec.header.size);
+ final int newEntryCount = dtohl(typeSpec.entryCount);
- if (typeSpec.id == 0) {
- ALOGW("ResTable_type has an id of 0.");
- return (mError=BAD_TYPE);
- }
+ if (kDebugLoadTableNoisy) {
+ ALOGI("TypeSpec off %s: type=0x%x, headerSize=0x%x, size=%s\n",
+ (base-chunk.myOffset()),
+ dtohs(typeSpec.header.type),
+ dtohs(typeSpec.header.headerSize),
+ typeSpecSize);
+ }
+ // look for block overrun or int overflow when multiplying by 4
+ if ((dtohl(typeSpec.entryCount) > (Integer.MAX_VALUE/4 /*sizeof(int)*/)
+ || dtohs(typeSpec.header.headerSize)+(4 /*sizeof(int)*/*newEntryCount)
+ > typeSpecSize)) {
+ ALOGW("ResTable_typeSpec entry index to %s extends beyond chunk end %s.",
+ (dtohs(typeSpec.header.headerSize) + (4 /*sizeof(int)*/*newEntryCount)),
+ typeSpecSize);
+ return (mError=BAD_TYPE);
+ }
- if (newEntryCount > 0) {
- boolean addToType = true;
- byte typeIndex = (byte) (typeSpec.id - 1);
- IdmapEntries idmapEntry = idmapEntries.get(typeSpec.id);
- if (idmapEntry != null) {
- typeIndex = (byte) (idmapEntry.targetTypeId() - 1);
- } else if (header.resourceIDMap != NULL) {
- // This is an overlay, but the types in this overlay are not
- // overlaying anything according to the idmap. We can skip these
- // as they will otherwise conflict with the other resources in the package
- // without a mapping.
- addToType = false;
+ if (typeSpec.id == 0) {
+ ALOGW("ResTable_type has an id of 0.");
+ return (mError=BAD_TYPE);
}
- if (addToType) {
- List<Type> typeList = computeIfAbsent(group.types, (int) typeIndex, k -> new ArrayList<>());
- if (!typeList.isEmpty()) {
- final Type existingType = typeList.get(0);
- if (existingType.entryCount != newEntryCount && idmapEntry == null) {
- ALOGW("ResTable_typeSpec entry count inconsistent: given %d, previously %d",
- (int) newEntryCount, (int) existingType.entryCount);
- // We should normally abort here, but some legacy apps declare
- // resources in the 'android' package (old bug in AAPT).
- }
+ if (newEntryCount > 0) {
+ boolean addToType = true;
+ byte typeIndex = (byte) (typeSpec.id - 1);
+ IdmapEntries idmapEntry = idmapEntries.get(typeSpec.id);
+ if (idmapEntry != null) {
+ typeIndex = (byte) (idmapEntry.targetTypeId() - 1);
+ } else if (header.resourceIDMap != NULL) {
+ // This is an overlay, but the types in this overlay are not
+ // overlaying anything according to the idmap. We can skip these
+ // as they will otherwise conflict with the other resources in the package
+ // without a mapping.
+ addToType = false;
}
- Type t = new Type(header, _package, newEntryCount);
- t.typeSpec = typeSpec;
- t.typeSpecFlags = typeSpec.getSpecFlags();
- if (idmapEntry != null) {
- t.idmapEntries = idmapEntry;
+ if (addToType) {
+ List<Type> typeList = computeIfAbsent(group.types, (int) typeIndex, k -> new ArrayList<>());
+ if (!typeList.isEmpty()) {
+ final Type existingType = typeList.get(0);
+ if (existingType.entryCount != newEntryCount && idmapEntry == null) {
+ ALOGW("ResTable_typeSpec entry count inconsistent: given %d, previously %d",
+ (int) newEntryCount, (int) existingType.entryCount);
+ // We should normally abort here, but some legacy apps declare
+ // resources in the 'android' package (old bug in AAPT).
+ }
+ }
+
+ Type t = new Type(header, _package, newEntryCount);
+ t.typeSpec = typeSpec;
+ t.typeSpecFlags = typeSpec.getSpecFlags();
+ if (idmapEntry != null) {
+ t.idmapEntries = idmapEntry;
+ }
+ typeList.add(t);
+ group.largestTypeId = max(group.largestTypeId, typeSpec.id);
}
- typeList.add(t);
- group.largestTypeId = max(group.largestTypeId, typeSpec.id);
+ } else {
+ ALOGV("Skipping empty ResTable_typeSpec for type %d", typeSpec.id);
}
- } else {
- ALOGV("Skipping empty ResTable_typeSpec for type %d", typeSpec.id);
- }
-
- } else if (ctype == RES_TABLE_TYPE_TYPE) {
- ResTable_type type = new ResTable_type(chunk.myBuf(), chunk.myOffset());
- err = validate_chunk(type.header, ResTable_type.SIZEOF_WITHOUT_CONFIG/*-sizeof(ResTable_config)*/+4,
- endPos, "ResTable_type");
- if (err != NO_ERROR) {
- return (mError=err);
- }
- final int typeSize = dtohl(type.header.size);
- final int newEntryCount = dtohl(type.entryCount);
+ } else if (ctype == RES_TABLE_TYPE_TYPE) {
+ ResTable_type type = new ResTable_type(chunk.myBuf(), chunk.myOffset());
+ err = validate_chunk(type.header, ResTable_type.SIZEOF_WITHOUT_CONFIG/*-sizeof(ResTable_config)*/+4,
+ endPos, "ResTable_type");
+ if (err != NO_ERROR) {
+ return (mError=err);
+ }
- if (kDebugLoadTableNoisy) {
- System.out.println(String.format("Type off 0x%x: type=0x%x, headerSize=0x%x, size=%d\n",
- base-chunk.myOffset(),
- dtohs(type.header.type),
- dtohs(type.header.headerSize),
- typeSize));
- }
- if (dtohs(type.header.headerSize)+(4/*sizeof(int)*/*newEntryCount) > typeSize) {
- ALOGW("ResTable_type entry index to %s extends beyond chunk end 0x%x.",
- (dtohs(type.header.headerSize) + (4/*sizeof(int)*/*newEntryCount)),
- typeSize);
- return (mError=BAD_TYPE);
- }
+ final int typeSize = dtohl(type.header.size);
+ final int newEntryCount = dtohl(type.entryCount);
- if (newEntryCount != 0
- && dtohl(type.entriesStart) > (typeSize- ResTable_entry.SIZEOF)) {
- ALOGW("ResTable_type entriesStart at 0x%x extends beyond chunk end 0x%x.",
- dtohl(type.entriesStart), typeSize);
- return (mError=BAD_TYPE);
- }
+ if (kDebugLoadTableNoisy) {
+ System.out.println(String.format("Type off 0x%x: type=0x%x, headerSize=0x%x, size=%d\n",
+ base-chunk.myOffset(),
+ dtohs(type.header.type),
+ dtohs(type.header.headerSize),
+ typeSize));
+ }
+ if (dtohs(type.header.headerSize)+(4/*sizeof(int)*/*newEntryCount) > typeSize) {
+ ALOGW("ResTable_type entry index to %s extends beyond chunk end 0x%x.",
+ (dtohs(type.header.headerSize) + (4/*sizeof(int)*/*newEntryCount)),
+ typeSize);
+ return (mError=BAD_TYPE);
+ }
- if (type.id == 0) {
- ALOGW("ResTable_type has an id of 0.");
- return (mError=BAD_TYPE);
- }
+ if (newEntryCount != 0
+ && dtohl(type.entriesStart) > (typeSize- ResTable_entry.SIZEOF)) {
+ ALOGW("ResTable_type entriesStart at 0x%x extends beyond chunk end 0x%x.",
+ dtohl(type.entriesStart), typeSize);
+ return (mError=BAD_TYPE);
+ }
- if (newEntryCount > 0) {
- boolean addToType = true;
- byte typeIndex = (byte) (type.id - 1);
- IdmapEntries idmapEntry = idmapEntries.get(type.id);
- if (idmapEntry != null) {
- typeIndex = (byte) (idmapEntry.targetTypeId() - 1);
- } else if (header.resourceIDMap != NULL) {
- // This is an overlay, but the types in this overlay are not
- // overlaying anything according to the idmap. We can skip these
- // as they will otherwise conflict with the other resources in the package
- // without a mapping.
- addToType = false;
+ if (type.id == 0) {
+ ALOGW("ResTable_type has an id of 0.");
+ return (mError=BAD_TYPE);
}
- if (addToType) {
- List<Type> typeList = getOrDefault(group.types, (int) typeIndex, Collections.emptyList());
- if (typeList.isEmpty()) {
- ALOGE("No TypeSpec for type %d", type.id);
- return (mError = BAD_TYPE);
+ if (newEntryCount > 0) {
+ boolean addToType = true;
+ byte typeIndex = (byte) (type.id - 1);
+ IdmapEntries idmapEntry = idmapEntries.get(type.id);
+ if (idmapEntry != null) {
+ typeIndex = (byte) (idmapEntry.targetTypeId() - 1);
+ } else if (header.resourceIDMap != NULL) {
+ // This is an overlay, but the types in this overlay are not
+ // overlaying anything according to the idmap. We can skip these
+ // as they will otherwise conflict with the other resources in the package
+ // without a mapping.
+ addToType = false;
}
- Type t = typeList.get(typeList.size() - 1);
- if (newEntryCount != t.entryCount) {
- ALOGE("ResTable_type entry count inconsistent: given %d, previously %d",
- (int) newEntryCount, (int) t.entryCount);
- return (mError = BAD_TYPE);
- }
+ if (addToType) {
+ List<Type> typeList = getOrDefault(group.types, (int) typeIndex, Collections.emptyList());
+ if (typeList.isEmpty()) {
+ ALOGE("No TypeSpec for type %d", type.id);
+ return (mError = BAD_TYPE);
+ }
- if (t._package_ != _package) {
- ALOGE("No TypeSpec for type %d", type.id);
- return (mError = BAD_TYPE);
- }
+ Type t = typeList.get(typeList.size() - 1);
+ if (newEntryCount != t.entryCount) {
+ ALOGE("ResTable_type entry count inconsistent: given %d, previously %d",
+ (int) newEntryCount, (int) t.entryCount);
+ return (mError = BAD_TYPE);
+ }
+
+ if (t._package_ != _package) {
+ ALOGE("No TypeSpec for type %d", type.id);
+ return (mError = BAD_TYPE);
+ }
- t.configs.add(type);
+ t.configs.add(type);
- if (kDebugTableGetEntry) {
- ResTable_config thisConfig = ResTable_config.fromDtoH(type.config);
- ALOGI("Adding config to type %d: %s\n", type.id,
- thisConfig.toString());
+ if (kDebugTableGetEntry) {
+ ResTable_config thisConfig = ResTable_config.fromDtoH(type.config);
+ ALOGI("Adding config to type %d: %s\n", type.id,
+ thisConfig.toString());
+ }
}
+ } else {
+ ALOGV("Skipping empty ResTable_type for type %d", type.id);
}
- } else {
- ALOGV("Skipping empty ResTable_type for type %d", type.id);
- }
- } else if (ctype == RES_TABLE_LIBRARY_TYPE) {
- if (group.dynamicRefTable.entries().isEmpty()) {
- throw new UnsupportedOperationException("libraries not supported yet");
+ } else if (ctype == RES_TABLE_LIBRARY_TYPE) {
+ if (group.dynamicRefTable.entries().isEmpty()) {
+ throw new UnsupportedOperationException("libraries not supported yet");
// const ResTable_lib_header* lib = (const ResTable_lib_header*) chunk;
// status_t err = validate_chunk(&lib->header, sizeof(*lib),
// endPos, "ResTable_lib_header");
@@ -1029,18 +1029,18 @@ public class ResTable {
// for (size_t i = 0; i < N; i++) {
// group.dynamicRefTable.addMapping(mPackageGroups[i].name, mPackageGroups[i].id);
// }
+ } else {
+ ALOGW("Found multiple library tables, ignoring...");
+ }
} else {
- ALOGW("Found multiple library tables, ignoring...");
- }
- } else {
- err = validate_chunk(chunk, ResChunk_header.SIZEOF,
- endPos, "ResTable_package:unknown");
- if (err != NO_ERROR) {
- return (mError=err);
+ err = validate_chunk(chunk, ResChunk_header.SIZEOF,
+ endPos, "ResTable_package:unknown");
+ if (err != NO_ERROR) {
+ return (mError=err);
+ }
}
- }
chunk = chunk.myOffset() + csize < endPos ? new ResChunk_header(chunk.myBuf(), chunk.myOffset() + csize) : null;
- }
+ }
return NO_ERROR;
}
@@ -1068,17 +1068,17 @@ public class ResTable {
// Find which configurations match the set of parameters. This allows for a much
// faster lookup in getEntry() if the set of values is narrowed down.
//for (int t = 0; t < packageGroup.types.size(); t++) {
- //if (packageGroup.types.get(t).isEmpty()) {
- // continue;
- // }
- //
- // List<Type> typeList = packageGroup.types.get(t);
- for (List<Type> typeList : packageGroup.types.values()) {
- if (typeList.isEmpty()) {
- continue;
+ //if (packageGroup.types.get(t).isEmpty()) {
+ // continue;
+ // }
+ //
+ // List<Type> typeList = packageGroup.types.get(t);
+ for (List<Type> typeList : packageGroup.types.values()) {
+ if (typeList.isEmpty()) {
+ continue;
}
- // Retrieve the cache entry for this type.
+ // Retrieve the cache entry for this type.
//TypeCacheEntry cacheEntry = packageGroup.typeCacheEntries.editItemAt(t);
for (int ts = 0; ts < typeList.size(); ts++) {
@@ -1195,14 +1195,14 @@ public class ResTable {
if (name[nameIndex] == '*') {
fakePublic = true;
nameIndex++;
+ }
}
- }
if (nameIndex >= nameEnd) {
return 0;
}
if (packageEnd != -1) {
- packageName = nameString.substring(nameIndex, packageEnd);
- nameIndex = packageEnd+1;
+ packageName = nameString.substring(nameIndex, packageEnd);
+ nameIndex = packageEnd+1;
} else if (packageName == null) {
return 0;
}
@@ -1229,7 +1229,7 @@ public class ResTable {
for (PackageGroup group : mPackageGroups.values()) {
if (!Objects.equals(packageName.trim(), group.name.trim())) {
if (kDebugTableNoisy) {
- System.out.println(String.format("Skipping package group: %s\n", group.name));
+ System.out.println(String.format("Skipping package group: %s\n", group.name));
}
continue;
}
@@ -1245,7 +1245,7 @@ public class ResTable {
int identifier = findEntry(group, ti, nameString, outTypeSpecFlags);
if (identifier != 0) {
if (fakePublic && outTypeSpecFlags != null) {
- outTypeSpecFlags.set(outTypeSpecFlags.get() | ResTable_typeSpec.SPEC_PUBLIC);
+ outTypeSpecFlags.set(outTypeSpecFlags.get() | ResTable_typeSpec.SPEC_PUBLIC);
}
return identifier;
}
@@ -2570,12 +2570,13 @@ public class ResTable {
// Gets cleared whenever the parameters/configuration changes.
// These are stored here in a parallel structure because the data in `types` may
// be shared by other ResTable's (framework resources are shared this way).
- ByteBucketArray<TypeCacheEntry> typeCacheEntries = new ByteBucketArray<TypeCacheEntry>() {
- @Override
- TypeCacheEntry newInstance() {
- return new TypeCacheEntry();
- }
- };
+ ByteBucketArray<TypeCacheEntry> typeCacheEntries =
+ new ByteBucketArray<TypeCacheEntry>(new TypeCacheEntry()) {
+ @Override
+ TypeCacheEntry newInstance() {
+ return new TypeCacheEntry();
+ }
+ };
// The table mapping dynamic references to resolved references for
// this package group.
@@ -2594,7 +2595,7 @@ public class ResTable {
// --------------------------------------------------------------------
// --------------------------------------------------------------------
-// struct ResTable::Header
+ // struct ResTable::Header
public static class Header
{
// Header(ResTable* _owner) : owner(_owner), ownedData(NULL), header(NULL),
@@ -2645,8 +2646,8 @@ public class ResTable {
public List<ResTable_type> configs;
public Type(final Header _header, final Package _package, int count)
- // : header(_header), package(_package), entryCount(count),
- // typeSpec(NULL), typeSpecFlags(NULL) { }
+ // : header(_header), package(_package), entryCount(count),
+ // typeSpec(NULL), typeSpecFlags(NULL) { }
{
this.header = _header;
_package_ = _package;
@@ -2657,7 +2658,7 @@ public class ResTable {
}
}
-// struct ResTable::Package
+ // struct ResTable::Package
public static class Package {
// Package(ResTable* _owner, final Header* _header, final ResTable_package* _package)
// : owner(_owner), header(_header), package(_package), typeIdOffset(0) {
@@ -2910,7 +2911,7 @@ public class ResTable {
// This is a new attribute... figure out what to do with it.
if (set.numAttrs >= set.availAttrs) {
// Need to alloc more memory...
- final int newAvail = set.availAttrs+N;
+ final int newAvail = set.availAttrs+N;
// set = (bag_set[])realloc(set,
// sizeof(bag_set)
// + sizeof(bag_entry)*newAvail);
diff --git a/resources/src/main/java/org/robolectric/res/android/ResTableTheme.java b/resources/src/main/java/org/robolectric/res/android/ResTableTheme.java
index 89954c4c5..3efeca3af 100644
--- a/resources/src/main/java/org/robolectric/res/android/ResTableTheme.java
+++ b/resources/src/main/java/org/robolectric/res/android/ResTableTheme.java
@@ -23,8 +23,8 @@ import org.robolectric.res.android.ResTable.bag_entry;
import org.robolectric.res.android.ResourceTypes.Res_value;
// transliterated from
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/ResourceTypes.cpp and
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/include/androidfw/ResourceTypes.h
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/ResourceTypes.cpp and
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/include/androidfw/ResourceTypes.h
public class ResTableTheme {
diff --git a/resources/src/main/java/org/robolectric/res/android/ResTable_config.java b/resources/src/main/java/org/robolectric/res/android/ResTable_config.java
index 2815d2e66..e85353af2 100644
--- a/resources/src/main/java/org/robolectric/res/android/ResTable_config.java
+++ b/resources/src/main/java/org/robolectric/res/android/ResTable_config.java
@@ -76,8 +76,8 @@ import javax.annotation.Nonnull;
* Describes a particular resource configuration.
*
* Transliterated from:
- * * https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/ResourceTypes.cpp
- * * https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/include/ResourceTypes.h (struct ResTable_config)
+ * * https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/ResourceTypes.cpp
+ * * https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/include/ResourceTypes.h (struct ResTable_config)
*
* Changes from 8.0.0_r4 partially applied.
*/
@@ -226,7 +226,7 @@ public class ResTable_config {
public static final int LAYOUTDIR_RTL = ACONFIGURATION_LAYOUTDIR_RTL << SHIFT_LAYOUTDIR;
public static final int SCREENWIDTH_ANY = 0;
-// public static final int MASK_SCREENSIZE = 0x0f;
+ // public static final int MASK_SCREENSIZE = 0x0f;
public static final int SCREENSIZE_ANY = ACONFIGURATION_SCREENSIZE_ANY;
public static final int SCREENSIZE_SMALL = ACONFIGURATION_SCREENSIZE_SMALL;
public static final int SCREENSIZE_NORMAL = ACONFIGURATION_SCREENSIZE_NORMAL;
@@ -862,7 +862,7 @@ public class ResTable_config {
// screenHeightDp = dtohs(screenHeightDp);
// }
-// void ResTable_config::copyFromDtoH(const ResTable_config& o) {
+ // void ResTable_config::copyFromDtoH(const ResTable_config& o) {
static ResTable_config fromDtoH(final ResTable_config o) {
return new ResTable_config(
0 /*sizeof(ResTable_config)*/,
@@ -1017,49 +1017,49 @@ public class ResTable_config {
}
int compare(final ResTable_config o) {
- if (imsi() != o.imsi()) {
- return (imsi() > o.imsi()) ? 1 : -1;
- }
-
- int diff = compareLocales(this, o);
- if (diff < 0) {
- return -1;
- }
- if (diff > 0) {
- return 1;
- }
-
- if (screenType() != o.screenType()) {
- return (screenType() > o.screenType()) ? 1 : -1;
- }
- if (input() != o.input()) {
- return (input() > o.input()) ? 1 : -1;
- }
- if (screenSize() != o.screenSize()) {
- return (screenSize() > o.screenSize()) ? 1 : -1;
- }
- if (version() != o.version()) {
- return (version() > o.version()) ? 1 : -1;
- }
- if (screenLayout != o.screenLayout) {
- return (screenLayout > o.screenLayout) ? 1 : -1;
- }
- if (screenLayout2 != o.screenLayout2) {
- return (screenLayout2 > o.screenLayout2) ? 1 : -1;
- }
- if (colorMode != o.colorMode) {
- return (colorMode > o.colorMode) ? 1 : -1;
- }
- if (uiMode != o.uiMode) {
- return (uiMode > o.uiMode) ? 1 : -1;
- }
- if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
- return (smallestScreenWidthDp > o.smallestScreenWidthDp) ? 1 : -1;
- }
- if (screenSizeDp() != o.screenSizeDp()) {
- return (screenSizeDp() > o.screenSizeDp()) ? 1 : -1;
- }
- return 0;
+ if (imsi() != o.imsi()) {
+ return (imsi() > o.imsi()) ? 1 : -1;
+ }
+
+ int diff = compareLocales(this, o);
+ if (diff < 0) {
+ return -1;
+ }
+ if (diff > 0) {
+ return 1;
+ }
+
+ if (screenType() != o.screenType()) {
+ return (screenType() > o.screenType()) ? 1 : -1;
+ }
+ if (input() != o.input()) {
+ return (input() > o.input()) ? 1 : -1;
+ }
+ if (screenSize() != o.screenSize()) {
+ return (screenSize() > o.screenSize()) ? 1 : -1;
+ }
+ if (version() != o.version()) {
+ return (version() > o.version()) ? 1 : -1;
+ }
+ if (screenLayout != o.screenLayout) {
+ return (screenLayout > o.screenLayout) ? 1 : -1;
+ }
+ if (screenLayout2 != o.screenLayout2) {
+ return (screenLayout2 > o.screenLayout2) ? 1 : -1;
+ }
+ if (colorMode != o.colorMode) {
+ return (colorMode > o.colorMode) ? 1 : -1;
+ }
+ if (uiMode != o.uiMode) {
+ return (uiMode > o.uiMode) ? 1 : -1;
+ }
+ if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
+ return (smallestScreenWidthDp > o.smallestScreenWidthDp) ? 1 : -1;
+ }
+ if (screenSizeDp() != o.screenSizeDp()) {
+ return (screenSizeDp() > o.screenSizeDp()) ? 1 : -1;
+ }
+ return 0;
}
@@ -1358,10 +1358,10 @@ public class ResTable_config {
}
if (isTruthy(input()) || isTruthy(o.input())) {
- final int keysHidden = inputFlags & MASK_KEYSHIDDEN;
- final int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;
+ final int keysHidden = inputFlags & MASK_KEYSHIDDEN;
+ final int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;
if (keysHidden != oKeysHidden) {
- final int reqKeysHidden =
+ final int reqKeysHidden =
requested.inputFlags & MASK_KEYSHIDDEN;
if (isTruthy(reqKeysHidden)) {
@@ -1375,10 +1375,10 @@ public class ResTable_config {
}
}
- final int navHidden = inputFlags & MASK_NAVHIDDEN;
- final int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;
+ final int navHidden = inputFlags & MASK_NAVHIDDEN;
+ final int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;
if (navHidden != oNavHidden) {
- final int reqNavHidden =
+ final int reqNavHidden =
requested.inputFlags & MASK_NAVHIDDEN;
if (isTruthy(reqNavHidden)) {
@@ -1501,34 +1501,34 @@ public class ResTable_config {
}
if (screenConfig() != 0) {
- final int layoutDir = screenLayout&MASK_LAYOUTDIR;
- final int setLayoutDir = settings.screenLayout&MASK_LAYOUTDIR;
+ final int layoutDir = screenLayout&MASK_LAYOUTDIR;
+ final int setLayoutDir = settings.screenLayout&MASK_LAYOUTDIR;
if (layoutDir != 0 && layoutDir != setLayoutDir) {
return false;
}
- final int screenSize = screenLayout&MASK_SCREENSIZE;
- final int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
+ final int screenSize = screenLayout&MASK_SCREENSIZE;
+ final int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
// Any screen sizes for larger screens than the setting do not
// match.
if (screenSize != 0 && screenSize > setScreenSize) {
return false;
}
- final int screenLong = screenLayout&MASK_SCREENLONG;
- final int setScreenLong = settings.screenLayout&MASK_SCREENLONG;
+ final int screenLong = screenLayout&MASK_SCREENLONG;
+ final int setScreenLong = settings.screenLayout&MASK_SCREENLONG;
if (screenLong != 0 && screenLong != setScreenLong) {
return false;
}
- final int uiModeType = uiMode&MASK_UI_MODE_TYPE;
- final int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE;
+ final int uiModeType = uiMode&MASK_UI_MODE_TYPE;
+ final int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE;
if (uiModeType != 0 && uiModeType != setUiModeType) {
return false;
}
- final int uiModeNight = uiMode&MASK_UI_MODE_NIGHT;
- final int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT;
+ final int uiModeNight = uiMode&MASK_UI_MODE_NIGHT;
+ final int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT;
if (uiModeNight != 0 && uiModeNight != setUiModeNight) {
return false;
}
@@ -1540,8 +1540,8 @@ public class ResTable_config {
}
if (screenConfig2() != 0) {
- final int screenRound = screenLayout2 & MASK_SCREENROUND;
- final int setScreenRound = settings.screenLayout2 & MASK_SCREENROUND;
+ final int screenRound = screenLayout2 & MASK_SCREENROUND;
+ final int setScreenRound = settings.screenLayout2 & MASK_SCREENROUND;
if (screenRound != 0 && screenRound != setScreenRound) {
return false;
}
@@ -1585,8 +1585,8 @@ public class ResTable_config {
}
}
if (input() != 0) {
- final int keysHidden = inputFlags&MASK_KEYSHIDDEN;
- final int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
+ final int keysHidden = inputFlags&MASK_KEYSHIDDEN;
+ final int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
if (keysHidden != 0 && keysHidden != setKeysHidden) {
// For compatibility, we count a request for KEYSHIDDEN_NO as also
// matching the more recent KEYSHIDDEN_SOFT. Basically
@@ -1601,8 +1601,8 @@ public class ResTable_config {
return false;
}
}
- final int navHidden = inputFlags&MASK_NAVHIDDEN;
- final int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;
+ final int navHidden = inputFlags&MASK_NAVHIDDEN;
+ final int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;
if (navHidden != 0 && navHidden != setNavHidden) {
return false;
}
@@ -1996,14 +1996,14 @@ public class ResTable_config {
}
/**
- union {
- struct {
- uint8_t orientation;
- uint8_t touchscreen;
- uint16_t density;
- };
- uint32_t screenType;
- };
+ union {
+ struct {
+ uint8_t orientation;
+ uint8_t touchscreen;
+ uint16_t density;
+ };
+ uint32_t screenType;
+ };
*/
private int screenType() {
return ((orientation & 0xff) << 24) | ((touchscreen & 0xff) << 16) | (density & 0xffff);
@@ -2171,14 +2171,14 @@ public class ResTable_config {
// The variants are the same, try numbering system.
boolean localeNumsysMatches = arrayCompare(localeNumberingSystem,
- requested.localeNumberingSystem
- ) == 0;
+ requested.localeNumberingSystem
+ ) == 0;
boolean otherNumsysMatches = arrayCompare(o.localeNumberingSystem,
- requested.localeNumberingSystem
- ) == 0;
+ requested.localeNumberingSystem
+ ) == 0;
if (localeNumsysMatches != otherNumsysMatches) {
- return localeNumsysMatches;
+ return localeNumsysMatches;
}
// Finally, the languages, although equivalent, may still be different
diff --git a/resources/src/main/java/org/robolectric/res/android/ResourceTypes.java b/resources/src/main/java/org/robolectric/res/android/ResourceTypes.java
index 81a1994a4..4591d7de6 100644
--- a/resources/src/main/java/org/robolectric/res/android/ResourceTypes.java
+++ b/resources/src/main/java/org/robolectric/res/android/ResourceTypes.java
@@ -16,8 +16,8 @@ import java.util.List;
import java.util.Map;
import org.robolectric.res.android.ResourceTypes.ResStringPool_header.Writer;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/ResourceTypes.cpp
-// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/include/androidfw/ResourceTypes.h
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/ResourceTypes.cpp
+// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/include/androidfw/ResourceTypes.h
public class ResourceTypes {
public static final String ANDROID_NS = "http://schemas.android.com/apk/res/android";
public static final String AUTO_NS = "http://schemas.android.com/apk/res-auto";
@@ -378,33 +378,33 @@ public class ResourceTypes {
}
}
-/**
- * This is a reference to a unique entry (a ResTable_entry structure)
- * in a resource table. The value is structured as: 0xpptteeee,
- * where pp is the package index, tt is the type index in that
- * package, and eeee is the entry index in that type. The package
- * and type values start at 1 for the first item, to help catch cases
- * where they have not been supplied.
- */
-public static class ResTable_ref
- {
- public static final int SIZEOF = 4;
-
- public int ident;
-
- public ResTable_ref(ByteBuffer buf, int offset) {
- ident = buf.getInt(offset);
- }
+ /**
+ * This is a reference to a unique entry (a ResTable_entry structure)
+ * in a resource table. The value is structured as: 0xpptteeee,
+ * where pp is the package index, tt is the type index in that
+ * package, and eeee is the entry index in that type. The package
+ * and type values start at 1 for the first item, to help catch cases
+ * where they have not been supplied.
+ */
+ public static class ResTable_ref
+ {
+ public static final int SIZEOF = 4;
- public ResTable_ref() {
- ident = 0;
- }
+ public int ident;
- @Override
- public String toString() {
- return "ResTable_ref{ident=" + ident + '}';
- }
- };
+ public ResTable_ref(ByteBuffer buf, int offset) {
+ ident = buf.getInt(offset);
+ }
+
+ public ResTable_ref() {
+ ident = 0;
+ }
+
+ @Override
+ public String toString() {
+ return "ResTable_ref{ident=" + ident + '}';
+ }
+ };
/**
* Reference to a string in a string pool.
@@ -441,7 +441,7 @@ public static class ResTable_ref
*********************************************************************** */
-/**
+ /**
* Definition for a pool of strings. The data of this chunk is an
* array of uint32_t providing indices into the pool, relative to
* stringsStart. At stringsStart are all of the UTF-16 strings
@@ -476,9 +476,9 @@ public static class ResTable_ref
// on strcmp16()).
public static final int SORTED_FLAG = 1<<0;
- // String pool is encoded in UTF-8
- public static final int UTF8_FLAG = 1<<8;
-// };
+ // String pool is encoded in UTF-8
+ public static final int UTF8_FLAG = 1<<8;
+ // };
final int flags;
// Index from header of the string data.
@@ -1253,10 +1253,10 @@ public static class ResTable_ref
short idxOrOffset;
// struct {
- // The index of the entry.
+ // The index of the entry.
// uint16_t idx;
- // The offset from ResTable_type::entriesStart, divided by 4.
+ // The offset from ResTable_type::entriesStart, divided by 4.
// uint16_t offset;
// };
diff --git a/resources/src/main/java/org/robolectric/res/android/ResourceUtils.java b/resources/src/main/java/org/robolectric/res/android/ResourceUtils.java
index 3a5b20e42..66664faff 100644
--- a/resources/src/main/java/org/robolectric/res/android/ResourceUtils.java
+++ b/resources/src/main/java/org/robolectric/res/android/ResourceUtils.java
@@ -1,8 +1,8 @@
package org.robolectric.res.android;
// transliterated from
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/include/androidfw/ResourceUtils.h
-// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/libs/androidfw/ResourceUtils.cpp
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/include/androidfw/ResourceUtils.h
+// and https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/libs/androidfw/ResourceUtils.cpp
class ResourceUtils {
// Extracts the package, type, and name from a string of the format: [[package:]type/]name
// Validation must be performed on each extracted piece.
@@ -72,7 +72,7 @@ class ResourceUtils {
// }
static boolean ExtractResourceName(String str, Ref<String> out_package, Ref<String> out_type,
- final Ref<String> out_entry) {
+ final Ref<String> out_entry) {
out_package.set("");
out_type.set("");
boolean has_package_separator = false;
@@ -95,7 +95,7 @@ class ResourceUtils {
out_entry.set(str.substring(start, end));
return !(has_package_separator && out_package.get().isEmpty()) &&
- !(has_type_separator && out_type.get().isEmpty());
+ !(has_type_separator && out_type.get().isEmpty());
}
}
diff --git a/resources/src/main/java/org/robolectric/res/android/String8.java b/resources/src/main/java/org/robolectric/res/android/String8.java
index 1da9fc0ab..9dcaa1e83 100644
--- a/resources/src/main/java/org/robolectric/res/android/String8.java
+++ b/resources/src/main/java/org/robolectric/res/android/String8.java
@@ -2,8 +2,8 @@ package org.robolectric.res.android;
import java.io.File;
-// transliterated from https://android.googlesource.com/platform/system/core/+/android-9.0.0_r3/libutils/String8.cpp
-// and https://android.googlesource.com/platform/system/core/+/android-9.0.0_r3/include/utils/String8.h
+// transliterated from https://android.googlesource.com/platform/system/core/+/android-9.0.0_r12/libutils/String8.cpp
+// and https://android.googlesource.com/platform/system/core/+/android-9.0.0_r12/include/utils/String8.h
public class String8 {
private StringBuilder mString;
@@ -27,7 +27,7 @@ public class String8 {
int length() {
return mString.length();
}
-//String8 String8::format(const char* fmt, ...)
+ //String8 String8::format(const char* fmt, ...)
//{
// va_list args;
// va_start(args, fmt);
@@ -98,11 +98,11 @@ public class String8 {
// }
// return real_append(other.string(), otherLen);
//}
-public String8 append(final String other) {
- mString.append(other);
+ public String8 append(final String other) {
+ mString.append(other);
return this;
-}
-//status_t String8::append(const char* other, size_t otherLen)
+ }
+ //status_t String8::append(const char* other, size_t otherLen)
//{
// if (bytes() == 0) {
// return setTo(other, otherLen);
@@ -288,16 +288,16 @@ public String8 append(final String other) {
// buf[len] = '\0';
// unlockBuffer(len);
//}
-String8 getPathLeaf() {
- final int cp;
- final String buf = mString.toString();
- cp = buf.lastIndexOf(File.separatorChar);
- if (cp == -1) {
- return new String8(this);
- } else {
- return new String8(buf.substring(cp + 1));
+ String8 getPathLeaf() {
+ final int cp;
+ final String buf = mString.toString();
+ cp = buf.lastIndexOf(File.separatorChar);
+ if (cp == -1) {
+ return new String8(this);
+ } else {
+ return new String8(buf.substring(cp + 1));
+ }
}
-}
//String8 String8::getPathDir(void) const
//{
// const char* cp;
@@ -329,13 +329,13 @@ String8 getPathLeaf() {
// return res;
//}
-/*
- * Helper function for finding the start of an extension in a pathname.
- *
- * Returns a index inside mString, or -1 if no extension was found.
- */
-private int find_extension()
-{
+ /*
+ * Helper function for finding the start of an extension in a pathname.
+ *
+ * Returns a index inside mString, or -1 if no extension was found.
+ */
+ private int find_extension()
+ {
int lastSlashIndex;
final StringBuilder str = mString;
@@ -348,10 +348,10 @@ private int find_extension()
}
// find the last dot
return str.lastIndexOf(".", lastSlashIndex);
-}
+ }
-public String getPathExtension()
-{
+ public String getPathExtension()
+ {
int extIndex;
extIndex = find_extension();
if (extIndex != -1) {
@@ -360,7 +360,7 @@ public String getPathExtension()
else {
return "";
}
-}
+ }
String8 getBasePath() {
int extIndex;
@@ -382,7 +382,7 @@ public String getPathExtension()
}
mString.append(name);
return this;
-}
+ }
//String8& String8::convertToResPath()
//{
diff --git a/resources/src/main/java/org/robolectric/res/android/StringPoolRef.java b/resources/src/main/java/org/robolectric/res/android/StringPoolRef.java
index 1d4e8e6a0..9c67304b7 100644
--- a/resources/src/main/java/org/robolectric/res/android/StringPoolRef.java
+++ b/resources/src/main/java/org/robolectric/res/android/StringPoolRef.java
@@ -1,7 +1,7 @@
package org.robolectric.res.android;
/**
- * transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/include/androidfw/ResourceTypes.h:541
+ * transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/include/androidfw/ResourceTypes.h:541
* Wrapper class that allows the caller to retrieve a string from a string pool without knowing
* which string pool to look.
*/
diff --git a/resources/src/test/java/org/robolectric/RoboSettingsTest.java b/resources/src/test/java/org/robolectric/RoboSettingsTest.java
index f306b3969..cef8f8538 100644
--- a/resources/src/test/java/org/robolectric/RoboSettingsTest.java
+++ b/resources/src/test/java/org/robolectric/RoboSettingsTest.java
@@ -15,12 +15,16 @@ public class RoboSettingsTest {
private String originalMavenRepositoryId;
private String originalMavenRepositoryUrl;
+ private String originalMavenRepositoryUserName;
+ private String originalMavenRepositoryPassword;
private boolean originalUseGlobalScheduler;
@Before
public void setUp() {
originalMavenRepositoryId = RoboSettings.getMavenRepositoryId();
originalMavenRepositoryUrl = RoboSettings.getMavenRepositoryUrl();
+ originalMavenRepositoryUserName = RoboSettings.getMavenRepositoryUserName();
+ originalMavenRepositoryPassword = RoboSettings.getMavenRepositoryPassword();
originalUseGlobalScheduler = RoboSettings.isUseGlobalScheduler();
}
@@ -28,6 +32,8 @@ public class RoboSettingsTest {
public void tearDown() {
RoboSettings.setMavenRepositoryId(originalMavenRepositoryId);
RoboSettings.setMavenRepositoryUrl(originalMavenRepositoryUrl);
+ RoboSettings.setMavenRepositoryUserName(originalMavenRepositoryUserName);
+ RoboSettings.setMavenRepositoryPassword(originalMavenRepositoryPassword);
RoboSettings.setUseGlobalScheduler(originalUseGlobalScheduler);
}
@@ -54,6 +60,18 @@ public class RoboSettingsTest {
}
@Test
+ public void setMavenRepositoryUserName() {
+ RoboSettings.setMavenRepositoryUserName("username");
+ assertEquals("username", RoboSettings.getMavenRepositoryUserName());
+ }
+
+ @Test
+ public void setMavenRepositoryPassword() {
+ RoboSettings.setMavenRepositoryPassword("password");
+ assertEquals("password", RoboSettings.getMavenRepositoryPassword());
+ }
+
+ @Test
public void isUseGlobalScheduler_defaultFalse() {
assertFalse(RoboSettings.isUseGlobalScheduler());
}
diff --git a/robolectric/Android.mk b/robolectric/Android.mk
index 24fc2eaf2..8dcf8e7fa 100644
--- a/robolectric/Android.mk
+++ b/robolectric/Android.mk
@@ -19,9 +19,10 @@ LOCAL_JAVA_LIBRARIES := \
Robolectric_junit \
Robolectric_utils \
robolectric-host-android_all \
+ robolectric-host-androidx-test-ext-junit \
+ robolectric-host-androidx-test-monitor \
robolectric-host-monitor-1.0.2-alpha1 \
robolectric-maven-ant-tasks-2.1.3 \
- robolectric-host-androidx-test \
robolectric-bouncycastle-1.46 \
robolectric-asm-commons-6.0 \
robolectric-guava-25.1-jre \
@@ -61,10 +62,12 @@ LOCAL_JAVA_LIBRARIES := \
Robolectric_sandbox \
Robolectric_junit \
Robolectric_utils \
+ robolectric-host-androidx-test-ext-junit \
+ robolectric-host-androidx-test-monitor \
robolectric-host-monitor-1.0.2-alpha1 \
+ robolectric-host-androidx-test-core \
robolectric-maven-ant-tasks-2.1.3 \
robolectric-mockito-core-2.16.0 \
- robolectric-host-androidx-test \
robolectric-bouncycastle-1.46 \
robolectric-hamcrest-core-1.3 \
robolectric-sqlite4java-0.282 \
@@ -98,11 +101,13 @@ test_runtime_libraries := \
Robolectric_sandbox \
Robolectric_junit \
Robolectric_utils \
+ robolectric-host-androidx-test-ext-junit \
+ robolectric-host-androidx-test-monitor \
robolectric-host-monitor-1.0.2-alpha1 \
+ robolectric-host-androidx-test-core \
robolectric-byte-buddy-agent-1.6.5 \
robolectric-maven-ant-tasks-2.1.3 \
robolectric-mockito-core-2.16.0 \
- robolectric-host-androidx-test \
robolectric-bouncycastle-1.46 \
robolectric-hamcrest-core-1.3 \
robolectric-sqlite4java-0.282 \
@@ -128,7 +133,9 @@ include external/robolectric-shadows/run_robolectric_module_tests.mk
###########################################
robolectric_target_to_host_jars := \
robolectric-host-android_all:$(call intermediates-dir-for, JAVA_LIBRARIES, robolectric_android-all-stub,,COMMON)/classes-with-res.jar \
- robolectric-host-androidx-test:$(call java-lib-files, androidx.test.monitor) \
+ robolectric-host-androidx-test-core:$(call java-lib-files, androidx.test.core) \
+ robolectric-host-androidx-test-ext-junit:$(call java-lib-files, androidx.test.ext.junit) \
+ robolectric-host-androidx-test-monitor:$(call java-lib-files, androidx.test.monitor) \
robolectric-host-androidx:$(call java-lib-files, androidx.fragment_fragment) \
robolectric-host-android-support-v4:$(call java-lib-files, android-support-v4) \
robolectric-host-android-support-multidex:$(call java-lib-files, android-support-multidex) \
diff --git a/robolectric/build.gradle b/robolectric/build.gradle
index e8d2ce2fb..f47118f9f 100644
--- a/robolectric/build.gradle
+++ b/robolectric/build.gradle
@@ -1,7 +1,3 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
@@ -21,41 +17,38 @@ configurations {
project.sourceSets.test.compileClasspath += configurations.shadow
dependencies {
- // Project dependencies
- compile project(":annotations")
- compile project(":junit")
- compile project(":resources")
- compile project(":sandbox")
- compile project(":utils")
+ api project(":annotations")
+ api project(":junit")
+ api project(":resources")
+ api project(":sandbox")
+ api project(":utils")
// We need to have shadows-framework.jar on the runtime system classpath so ServiceLoader
// can find its META-INF/services/org.robolectric.shadows.ShadowAdapter.
- compile project(":shadows:framework")
+ api project(":shadows:framework")
- // Compile dependencies
- compile "org.bouncycastle:bcprov-jdk15on:1.52"
- compileOnly "com.google.code.findbugs:jsr305:3.0.1"
+ api "org.bouncycastle:bcprov-jdk15on:1.52"
+ compileOnly "com.google.code.findbugs:jsr305:3.0.2"
- compile "org.apache.ant:ant:1.8.0"
- compile("org.apache.maven:maven-ant-tasks:2.1.3") {
+ api "org.apache.ant:ant:1.8.0"
+ api("org.apache.maven:maven-ant-tasks:2.1.3") {
exclude group: "junit", module: "junit"
}
compileOnly AndroidSdk.MAX_SDK.coordinates
compileOnly "junit:junit:4.12"
- compileOnly "androidx.test:monitor:1.1.0-alpha4"
+ compile "androidx.test:monitor:1.1.0"
- // Testing dependencies
- testCompile "junit:junit:4.12"
- testCompile "com.google.truth:truth:0.39"
- testCompile "org.mockito:mockito-core:2.5.4"
- testCompile "androidx.test:core:1.0.0-alpha4"
+ testImplementation "junit:junit:4.12"
+ testImplementation "com.google.truth:truth:0.42"
+ testImplementation "org.mockito:mockito-core:2.5.4"
+ testImplementation "androidx.test:core:1.0.0"
+ testImplementation "androidx.test.ext:junit:1.0.0"
+ testImplementation "androidx.test:runner:1.1.0"
testCompileOnly AndroidSdk.MAX_SDK.coordinates // compile against latest Android SDK
testRuntime AndroidSdk.MAX_SDK.coordinates // run against whatever this JDK supports
}
test {
- systemProperty 'robolectric.resourcesMode', 'both'
-
if (project.hasProperty('maxParallelForks'))
maxParallelForks = project.maxParallelForks as int
if (project.hasProperty('forkEvery'))
diff --git a/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java b/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
index 76e89ac96..50d312ecf 100644
--- a/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
+++ b/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
@@ -359,6 +359,11 @@ public class RobolectricTestRunner extends SandboxTestRunner {
+ roboMethod.getMethod().getName() + ": sdk=" + sdkConfig.getApiLevel()
+ "; resources=" + roboMethod.resourcesMode);
+ if (roboMethod.resourcesMode == ResourcesMode.legacy) {
+ System.out.println(
+ "[Robolectric] NOTICE: legacy resources mode is deprecated; see http://robolectric.org/migrating/#migrating-to-40");
+ }
+
roboMethod.parallelUniverseInterface = getHooksInterface(sdkEnvironment);
Class<TestLifecycle> cl = sdkEnvironment.bootstrappedClass(getTestLifecycleClass());
roboMethod.testLifecycle = ReflectionHelpers.newInstance(cl);
diff --git a/robolectric/src/main/java/org/robolectric/SdkPicker.java b/robolectric/src/main/java/org/robolectric/SdkPicker.java
index 64542498e..0acfa142f 100644
--- a/robolectric/src/main/java/org/robolectric/SdkPicker.java
+++ b/robolectric/src/main/java/org/robolectric/SdkPicker.java
@@ -14,7 +14,6 @@ import javax.annotation.Nullable;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.internal.ConfigUtils;
import org.robolectric.internal.SdkConfig;
-import org.robolectric.manifest.AndroidManifest;
public class SdkPicker {
private final Set<SdkConfig> supportedSdks;
@@ -35,25 +34,6 @@ public class SdkPicker {
* Enumerate the SDKs to be used for this test.
*
* @param config a {@link Config} specifying one or more SDKs
- * @param appManifest the {@link AndroidManifest} for the test
- * @return the list of candidate {@link SdkConfig}s.
- * @since 3.2
- * @deprecated Use {@link #selectSdks(Config, UsesSdk)} instead.
- */
- @Deprecated
- @Nonnull
- public List<SdkConfig> selectSdks(Config config, AndroidManifest appManifest) {
- Set<SdkConfig> sdks = new TreeSet<>(configuredSdks(config, appManifest));
- if (enabledSdks != null) {
- sdks = Sets.intersection(sdks, enabledSdks);
- }
- return Lists.newArrayList(sdks);
- }
-
- /**
- * Enumerate the SDKs to be used for this test.
- *
- * @param config a {@link Config} specifying one or more SDKs
* @param usesSdk the {@link UsesSdk} for the test
* @return the list of candidate {@link SdkConfig}s.
* @since 3.9
@@ -80,12 +60,6 @@ public class SdkPicker {
}
}
- /** @deprecated Use {@link #configuredSdks(Config, UsesSdk)} instead. */
- @Deprecated
- protected Set<SdkConfig> configuredSdks(Config config, AndroidManifest appManifest) {
- return configuredSdks(config, (UsesSdk) appManifest);
- }
-
protected Set<SdkConfig> configuredSdks(Config config, UsesSdk usesSdk) {
int appMinSdk = Math.max(usesSdk.getMinSdkVersion(), minSupportedSdk.getApiLevel());
int appTargetSdk = Math.max(usesSdk.getTargetSdkVersion(), minSupportedSdk.getApiLevel());
@@ -170,15 +144,6 @@ public class SdkPicker {
}
@Nonnull
- private static List<SdkConfig> map(Collection<Integer> supportedSdks) {
- ArrayList<SdkConfig> sdkConfigs = new ArrayList<>();
- for (int supportedSdk : supportedSdks) {
- sdkConfigs.add(new SdkConfig(supportedSdk));
- }
- return sdkConfigs;
- }
-
- @Nonnull
static List<SdkConfig> map(int... supportedSdks) {
ArrayList<SdkConfig> sdkConfigs = new ArrayList<>();
for (int supportedSdk : supportedSdks) {
diff --git a/robolectric/src/main/java/org/robolectric/android/fakes/RoboMonitoringInstrumentation.java b/robolectric/src/main/java/org/robolectric/android/fakes/RoboMonitoringInstrumentation.java
index 8869078c7..15c4a91f8 100644
--- a/robolectric/src/main/java/org/robolectric/android/fakes/RoboMonitoringInstrumentation.java
+++ b/robolectric/src/main/java/org/robolectric/android/fakes/RoboMonitoringInstrumentation.java
@@ -5,7 +5,6 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import androidx.test.runner.MonitoringInstrumentation;
import org.robolectric.Robolectric;
-import org.robolectric.android.controller.ActivityController;
import org.robolectric.shadows.ShadowLooper;
public class RoboMonitoringInstrumentation extends MonitoringInstrumentation {
@@ -35,14 +34,15 @@ public class RoboMonitoringInstrumentation extends MonitoringInstrumentation {
ActivityInfo ai = intent.resolveActivityInfo(getTargetContext().getPackageManager(), 0);
try {
Class<? extends Activity> activityClass = Class.forName(ai.name).asSubclass(Activity.class);
- ActivityController<? extends Activity> controller = Robolectric.buildActivity(activityClass, intent);
- Activity activity = controller.get();
- callActivityOnCreate(activity, null);
- controller.postCreate(null);
- callActivityOnStart(activity);
- callActivityOnResume(activity);
- controller.visible().windowFocusChanged(true);
- return activity;
+ return Robolectric.buildActivity(activityClass, intent)
+ .create()
+ .postCreate(null)
+ .start()
+ .resume()
+ .postResume()
+ .visible()
+ .windowFocusChanged(true)
+ .get();
} catch (ClassNotFoundException e) {
throw new RuntimeException("Could not load activity " + ai.name, e);
}
diff --git a/robolectric/src/main/java/org/robolectric/android/internal/LocalActivityInvoker.java b/robolectric/src/main/java/org/robolectric/android/internal/LocalActivityInvoker.java
new file mode 100644
index 000000000..c85a71e11
--- /dev/null
+++ b/robolectric/src/main/java/org/robolectric/android/internal/LocalActivityInvoker.java
@@ -0,0 +1,190 @@
+package org.robolectric.android.internal;
+
+import static androidx.test.InstrumentationRegistry.getContext;
+import static androidx.test.InstrumentationRegistry.getTargetContext;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import android.app.Activity;
+import android.app.Instrumentation.ActivityResult;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.os.Bundle;
+import androidx.test.internal.platform.app.ActivityInvoker;
+import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
+import androidx.test.runner.lifecycle.Stage;
+import javax.annotation.Nullable;
+import org.robolectric.Robolectric;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowActivity;
+
+/**
+ * An {@link ActivityInvoker} that drives {@link Activity} lifecycles manually.
+ *
+ * <p>All the methods in this class are blocking API.
+ */
+public class LocalActivityInvoker implements ActivityInvoker {
+
+ @Nullable private ActivityController<? extends Activity> controller;
+
+ @Override
+ public void startActivity(Intent intent) {
+ ActivityInfo ai = intent.resolveActivityInfo(getTargetContext().getPackageManager(), 0);
+ try {
+ Class<? extends Activity> activityClass = Class.forName(ai.name).asSubclass(Activity.class);
+ controller =
+ Robolectric.buildActivity(activityClass, intent)
+ .create()
+ .postCreate(null)
+ .start()
+ .resume()
+ .postResume()
+ .visible()
+ .windowFocusChanged(true);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Could not load activity " + ai.name, e);
+ }
+ }
+
+
+ @Override
+ public void resumeActivity(Activity activity) {
+ checkNotNull(controller);
+ checkState(controller.get() == activity);
+ Stage stage = ActivityLifecycleMonitorRegistry.getInstance().getLifecycleStageOf(activity);
+ switch (stage) {
+ case RESUMED:
+ return;
+ case PAUSED:
+ controller.stop().restart().start().resume().postResume();
+ return;
+ case STOPPED:
+ controller.restart().start().resume().postResume();
+ return;
+ default:
+ throw new IllegalStateException(
+ String.format(
+ "Activity's stage must be RESUMED, PAUSED or STOPPED but was %s.", stage));
+ }
+ }
+
+ @Override
+ public void pauseActivity(Activity activity) {
+ checkNotNull(controller);
+ checkState(controller.get() == activity);
+ Stage stage = ActivityLifecycleMonitorRegistry.getInstance().getLifecycleStageOf(activity);
+ switch (stage) {
+ case RESUMED:
+ controller.pause();
+ return;
+ case PAUSED:
+ return;
+ default:
+ throw new IllegalStateException(
+ String.format("Activity's stage must be RESUMED or PAUSED but was %s.", stage));
+ }
+ }
+
+ @Override
+ public void stopActivity(Activity activity) {
+ checkNotNull(controller);
+ checkState(controller.get() == activity);
+ Stage stage = ActivityLifecycleMonitorRegistry.getInstance().getLifecycleStageOf(activity);
+ switch (stage) {
+ case RESUMED:
+ controller.pause().stop();
+ return;
+ case PAUSED:
+ controller.stop();
+ return;
+ case STOPPED:
+ return;
+ default:
+ throw new IllegalStateException(
+ String.format(
+ "Activity's stage must be RESUMED, PAUSED or STOPPED but was %s.", stage));
+ }
+ }
+
+ @Override
+ public void recreateActivity(Activity activity) {
+ checkNotNull(controller);
+ checkState(controller.get() == activity);
+ Stage originalStage =
+ ActivityLifecycleMonitorRegistry.getInstance().getLifecycleStageOf(activity);
+
+ // Move the activity stage to STOPPED before retrieving saveInstanceState.
+ stopActivity(activity);
+
+ Bundle outState = new Bundle();
+ controller.saveInstanceState(outState);
+ Object nonConfigInstance = activity.onRetainNonConfigurationInstance();
+ controller.destroy();
+
+ controller = Robolectric.buildActivity(activity.getClass(), activity.getIntent());
+ Activity recreatedActivity = controller.get();
+ Shadow.<ShadowActivity>extract(recreatedActivity)
+ .setLastNonConfigurationInstance(nonConfigInstance);
+ controller
+ .create(outState)
+ .postCreate(outState)
+ .start()
+ .restoreInstanceState(outState)
+ .resume()
+ .postResume()
+ .visible()
+ .windowFocusChanged(true);
+
+ // Move to the original stage.
+ switch (originalStage) {
+ case RESUMED:
+ return;
+ case PAUSED:
+ pauseActivity(recreatedActivity);
+ return;
+ case STOPPED:
+ stopActivity(recreatedActivity);
+ return;
+ default:
+ throw new IllegalStateException(
+ String.format(
+ "Activity's stage must be RESUMED, PAUSED or STOPPED but was %s.", originalStage));
+ }
+ }
+
+ @Override
+ public void finishActivity(Activity activity) {
+ checkNotNull(controller);
+ checkState(controller.get() == activity);
+ activity.finish();
+ Stage stage = ActivityLifecycleMonitorRegistry.getInstance().getLifecycleStageOf(activity);
+ switch (stage) {
+ case RESUMED:
+ controller.pause().stop().destroy();
+ return;
+ case PAUSED:
+ controller.stop().destroy();
+ return;
+ case STOPPED:
+ controller.destroy();
+ return;
+ default:
+ throw new IllegalStateException(
+ String.format(
+ "Activity's stage must be RESUMED, PAUSED or STOPPED but was %s.", stage));
+ }
+ }
+
+ // TODO: just copy implementation from super. It looks like 'default' keyword from super is
+ // getting stripped from androidx.test.monitor maven artifact
+ @Override
+ public Intent getIntentForActivity(Class<? extends Activity> activityClass) {
+ Intent intent = Intent.makeMainActivity(new ComponentName(getTargetContext(), activityClass));
+ if (getTargetContext().getPackageManager().resolveActivity(intent, 0) != null) {
+ return intent;
+ }
+ return Intent.makeMainActivity(new ComponentName(getContext(), activityClass));
+ }
+}
diff --git a/robolectric/src/main/java/org/robolectric/android/internal/NoOpThreadChecker.java b/robolectric/src/main/java/org/robolectric/android/internal/NoOpThreadChecker.java
new file mode 100644
index 000000000..481009de8
--- /dev/null
+++ b/robolectric/src/main/java/org/robolectric/android/internal/NoOpThreadChecker.java
@@ -0,0 +1,15 @@
+package org.robolectric.android.internal;
+
+import androidx.test.internal.platform.ThreadChecker;
+
+/**
+ * In Robolectric environment, everything is executed on the main thread except for when you
+ * manually create and run your code on worker thread.
+ */
+public class NoOpThreadChecker implements ThreadChecker {
+ @Override
+ public void checkMainThread() {}
+
+ @Override
+ public void checkNotMainThread() {}
+}
diff --git a/robolectric/src/main/java/org/robolectric/android/internal/ParallelUniverse.java b/robolectric/src/main/java/org/robolectric/android/internal/ParallelUniverse.java
index 94064c44a..3afe6f970 100644
--- a/robolectric/src/main/java/org/robolectric/android/internal/ParallelUniverse.java
+++ b/robolectric/src/main/java/org/robolectric/android/internal/ParallelUniverse.java
@@ -1,6 +1,7 @@
package org.robolectric.android.internal;
import static android.location.LocationManager.GPS_PROVIDER;
+import static android.os.Build.VERSION_CODES.P;
import static org.robolectric.shadow.api.Shadow.newInstanceOf;
import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
@@ -130,7 +131,14 @@ public class ParallelUniverse implements ParallelUniverseInterface {
parsedPackage = new PackageParser.Package("org.robolectric.default");
parsedPackage.applicationInfo.targetSdkVersion = appManifest.getTargetSdkVersion();
}
-
+ // Support overriding the package name specified in the Manifest.
+ if (!Config.DEFAULT_PACKAGE_NAME.equals(config.packageName())) {
+ parsedPackage.packageName = config.packageName();
+ parsedPackage.applicationInfo.packageName = config.packageName();
+ } else {
+ parsedPackage.packageName = appManifest.getPackageName();
+ parsedPackage.applicationInfo.packageName = appManifest.getPackageName();
+ }
} else {
RuntimeEnvironment.compileTimeSystemResourcesFile =
apkLoader.getCompileTimeSystemResourcesFile(sdkEnvironment);
@@ -144,14 +152,11 @@ public class ParallelUniverse implements ParallelUniverseInterface {
ApplicationInfo applicationInfo = parsedPackage.applicationInfo;
- // Support overriding the package name specified in the Manifest.
- if (!Config.DEFAULT_PACKAGE_NAME.equals(config.packageName())) {
- parsedPackage.packageName = config.packageName();
- parsedPackage.applicationInfo.packageName = config.packageName();
- } else {
- parsedPackage.packageName = appManifest.getPackageName();
- parsedPackage.applicationInfo.packageName = appManifest.getPackageName();
+ // unclear why, but prior to P the processName wasn't set
+ if (sdkConfig.getApiLevel() < P && applicationInfo.processName == null) {
+ applicationInfo.processName = parsedPackage.packageName;
}
+
// TempDirectory tempDirectory = RuntimeEnvironment.getTempDirectory();
// packageInfo.setVolumeUuid(tempDirectory.createIfNotExists(packageInfo.packageName +
// "-dataDir").toAbsolutePath().toString());
diff --git a/robolectric/src/main/java/org/robolectric/internal/dependency/MavenDependencyResolver.java b/robolectric/src/main/java/org/robolectric/internal/dependency/MavenDependencyResolver.java
index d81f6732e..bee65b5c3 100644
--- a/robolectric/src/main/java/org/robolectric/internal/dependency/MavenDependencyResolver.java
+++ b/robolectric/src/main/java/org/robolectric/internal/dependency/MavenDependencyResolver.java
@@ -3,6 +3,8 @@ package org.robolectric.internal.dependency;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;
+
+import org.apache.maven.artifact.ant.Authentication;
import org.apache.maven.artifact.ant.DependenciesTask;
import org.apache.maven.artifact.ant.RemoteRepository;
import org.apache.maven.model.Dependency;
@@ -14,14 +16,18 @@ public class MavenDependencyResolver implements DependencyResolver {
private final Project project = new Project();
private final String repositoryUrl;
private final String repositoryId;
+ private final String repositoryUserName;
+ private final String repositoryPassword;
public MavenDependencyResolver() {
- this(RoboSettings.getMavenRepositoryUrl(), RoboSettings.getMavenRepositoryId());
+ this(RoboSettings.getMavenRepositoryUrl(), RoboSettings.getMavenRepositoryId(), RoboSettings.getMavenRepositoryUserName(), RoboSettings.getMavenRepositoryPassword());
}
- public MavenDependencyResolver(String repositoryUrl, String repositoryId) {
+ public MavenDependencyResolver(String repositoryUrl, String repositoryId, String repositoryUserName, String repositoryPassword) {
this.repositoryUrl = repositoryUrl;
this.repositoryId = repositoryId;
+ this.repositoryUserName = repositoryUserName;
+ this.repositoryPassword = repositoryPassword;
}
@Override
@@ -39,6 +45,12 @@ public class MavenDependencyResolver implements DependencyResolver {
RemoteRepository remoteRepository = new RemoteRepository();
remoteRepository.setUrl(repositoryUrl);
remoteRepository.setId(repositoryId);
+ if (repositoryUserName != null || repositoryPassword != null) {
+ Authentication authentication = new Authentication();
+ authentication.setUserName(repositoryUserName);
+ authentication.setPassword(repositoryPassword);
+ remoteRepository.addAuthentication(authentication);
+ }
dependenciesTask.addConfiguredRemoteRepository(remoteRepository);
dependenciesTask.setProject(project);
for (DependencyJar dependencyJar : dependencies) {
diff --git a/robolectric/src/main/resources/META-INF/services/androidx.test.internal.platform.ThreadChecker b/robolectric/src/main/resources/META-INF/services/androidx.test.internal.platform.ThreadChecker
new file mode 100644
index 000000000..55104eac2
--- /dev/null
+++ b/robolectric/src/main/resources/META-INF/services/androidx.test.internal.platform.ThreadChecker
@@ -0,0 +1 @@
+org.robolectric.android.internal.NoOpThreadChecker
diff --git a/robolectric/src/main/resources/META-INF/services/androidx.test.internal.platform.app.ActivityInvoker b/robolectric/src/main/resources/META-INF/services/androidx.test.internal.platform.app.ActivityInvoker
new file mode 100644
index 000000000..e9944b51e
--- /dev/null
+++ b/robolectric/src/main/resources/META-INF/services/androidx.test.internal.platform.app.ActivityInvoker
@@ -0,0 +1 @@
+org.robolectric.android.internal.LocalActivityInvoker
diff --git a/robolectric/src/test/java/org/robolectric/AttributeSetBuilderTest.java b/robolectric/src/test/java/org/robolectric/AttributeSetBuilderTest.java
index 61acac5dd..4531bbb02 100644
--- a/robolectric/src/test/java/org/robolectric/AttributeSetBuilderTest.java
+++ b/robolectric/src/test/java/org/robolectric/AttributeSetBuilderTest.java
@@ -8,16 +8,15 @@ import static org.robolectric.res.AttributeResource.ANDROID_RES_NS_PREFIX;
import static org.robolectric.res.AttributeResource.RES_AUTO_NS_URI;
import android.util.AttributeSet;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.robolectric.res.AttributeResource;
-/**
- * Tests for {@link Robolectric#buildAttributeSet()}
- */
-@RunWith(RobolectricTestRunner.class)
+/** Tests for {@link Robolectric#buildAttributeSet()} */
+@RunWith(AndroidJUnit4.class)
public class AttributeSetBuilderTest {
private static final String APP_NS = RES_AUTO_NS_URI;
diff --git a/robolectric/src/test/java/org/robolectric/IncludedDependenciesTest.java b/robolectric/src/test/java/org/robolectric/IncludedDependenciesTest.java
index 07f4daffd..8c8dc7398 100644
--- a/robolectric/src/test/java/org/robolectric/IncludedDependenciesTest.java
+++ b/robolectric/src/test/java/org/robolectric/IncludedDependenciesTest.java
@@ -2,6 +2,7 @@ package org.robolectric;
import static org.junit.Assert.assertEquals;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.StringReader;
import org.json.JSONObject;
import org.junit.Test;
@@ -9,7 +10,7 @@ import org.junit.runner.RunWith;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class IncludedDependenciesTest {
@Test
public void jsonShouldWork() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/InvokeDynamicTest.java b/robolectric/src/test/java/org/robolectric/InvokeDynamicTest.java
index d65fcee6a..109b52588 100644
--- a/robolectric/src/test/java/org/robolectric/InvokeDynamicTest.java
+++ b/robolectric/src/test/java/org/robolectric/InvokeDynamicTest.java
@@ -2,6 +2,7 @@ package org.robolectric;
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.annotation.Config;
@@ -11,7 +12,7 @@ import org.robolectric.annotation.RealObject;
import org.robolectric.annotation.internal.Instrument;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(sdk = Config.NEWEST_SDK)
public class InvokeDynamicTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/ManifestFactoryTest.java b/robolectric/src/test/java/org/robolectric/ManifestFactoryTest.java
index f1ee09812..903a8665e 100644
--- a/robolectric/src/test/java/org/robolectric/ManifestFactoryTest.java
+++ b/robolectric/src/test/java/org/robolectric/ManifestFactoryTest.java
@@ -41,17 +41,23 @@ public class ManifestFactoryTest {
ManifestFactory manifestFactory = testRunner.getManifestFactory(config);
assertThat(manifestFactory).isInstanceOf(DefaultManifestFactory.class);
ManifestIdentifier manifestIdentifier = manifestFactory.identify(config);
- assertThat(manifestIdentifier.getManifestFile()).isEqualTo(Fs.fileFromPath(baseDir + "/path/to/MergedManifest.xml"));
- assertThat(manifestIdentifier.getResDir()).isEqualTo(Fs.fileFromPath(baseDir + "/path/to/merged-resources"));
- assertThat(manifestIdentifier.getAssetDir()).isEqualTo(Fs.fileFromPath(baseDir + "/path/to/merged-assets"));
+ assertThat(manifestIdentifier.getManifestFile())
+ .isEqualTo(Fs.fileFromPath(baseDir + "/path/to/MergedManifest.xml"));
+ assertThat(manifestIdentifier.getResDir())
+ .isEqualTo(Fs.fileFromPath(baseDir + "/path/to/merged-resources"));
+ assertThat(manifestIdentifier.getAssetDir())
+ .isEqualTo(Fs.fileFromPath(baseDir + "/path/to/merged-assets"));
assertThat(manifestIdentifier.getLibraries()).isEmpty();
assertThat(manifestIdentifier.getPackageName()).isNull();
AndroidManifest androidManifest = RobolectricTestRunner
.createAndroidManifest(manifestIdentifier);
- assertThat(androidManifest.getAndroidManifestFile()).isEqualTo(Fs.fileFromPath(baseDir + "/path/to/MergedManifest.xml"));
- assertThat(androidManifest.getResDirectory()).isEqualTo(Fs.fileFromPath(baseDir + "/path/to/merged-resources"));
- assertThat(androidManifest.getAssetsDirectory()).isEqualTo(Fs.fileFromPath(baseDir + "/path/to/merged-assets"));
+ assertThat(androidManifest.getAndroidManifestFile())
+ .isEqualTo(Fs.fileFromPath(baseDir + "/path/to/MergedManifest.xml"));
+ assertThat(androidManifest.getResDirectory())
+ .isEqualTo(Fs.fileFromPath(baseDir + "/path/to/merged-resources"));
+ assertThat(androidManifest.getAssetsDirectory())
+ .isEqualTo(Fs.fileFromPath(baseDir + "/path/to/merged-assets"));
}
@Test
@@ -71,6 +77,9 @@ public class ManifestFactoryTest {
};
String baseDir = System.getProperty("robolectric-tests.base-dir");
+ if (baseDir == null) {
+ baseDir = "";
+ }
Config.Implementation config = Config.Builder.defaults()
.setManifest("TestAndroidManifest.xml")
@@ -81,9 +90,11 @@ public class ManifestFactoryTest {
ManifestIdentifier manifestIdentifier = manifestFactory.identify(config);
assertThat(manifestIdentifier.getManifestFile())
.isEqualTo(Fs.fromURL(getClass().getClassLoader().getResource("TestAndroidManifest.xml")));
- assertThat(manifestIdentifier.getResDir()).isEqualTo(Fs.fileFromPath(baseDir + "/path/to/merged-resources"));
- assertThat(manifestIdentifier.getAssetDir()).isEqualTo(Fs.fileFromPath(baseDir + "/path/to/merged-assets"));
+ assertThat(manifestIdentifier.getResDir())
+ .isEqualTo(Fs.fileFromPath(baseDir + "/path/to/merged-resources"));
+ assertThat(manifestIdentifier.getAssetDir())
+ .isEqualTo(Fs.fileFromPath(baseDir + "/path/to/merged-assets"));
assertThat(manifestIdentifier.getLibraries()).isEmpty();
assertThat(manifestIdentifier.getPackageName()).isEqualTo("another.package");
}
-}
+} \ No newline at end of file
diff --git a/robolectric/src/test/java/org/robolectric/QualifiersTest.java b/robolectric/src/test/java/org/robolectric/QualifiersTest.java
index bb21af990..f3cca59f9 100644
--- a/robolectric/src/test/java/org/robolectric/QualifiersTest.java
+++ b/robolectric/src/test/java/org/robolectric/QualifiersTest.java
@@ -1,6 +1,7 @@
package org.robolectric;
import static android.os.Build.VERSION_CODES.O;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
@@ -10,20 +11,21 @@ import android.content.res.Resources;
import android.os.Build.VERSION_CODES;
import android.view.View;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class QualifiersTest {
private Resources resources;
@Before
public void setUp() throws Exception {
- resources = RuntimeEnvironment.application.getResources();
+ resources = getApplicationContext().getResources();
}
@Test
@@ -107,7 +109,7 @@ public class QualifiersTest {
@Test @Config(qualifiers = "land")
public void setQualifiers_updatesSystemAndAppResources() throws Exception {
Resources systemResources = Resources.getSystem();
- Resources appResources = RuntimeEnvironment.application.getResources();
+ Resources appResources = getApplicationContext().getResources();
assertThat(systemResources.getConfiguration().orientation).isEqualTo(
Configuration.ORIENTATION_LANDSCAPE);
diff --git a/robolectric/src/test/java/org/robolectric/RobolectricTest.java b/robolectric/src/test/java/org/robolectric/RobolectricTest.java
index 0eb6d2edd..5ee979dc9 100644
--- a/robolectric/src/test/java/org/robolectric/RobolectricTest.java
+++ b/robolectric/src/test/java/org/robolectric/RobolectricTest.java
@@ -17,6 +17,8 @@ import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewParent;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.After;
@@ -31,7 +33,7 @@ import org.robolectric.shadows.ShadowLooper;
import org.robolectric.shadows.ShadowView;
import org.robolectric.util.ReflectionHelpers;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class RobolectricTest {
private PrintStream originalSystemOut;
@@ -48,7 +50,7 @@ public class RobolectricTest {
buff = new ByteArrayOutputStream();
PrintStream testOut = new PrintStream(buff);
System.setOut(testOut);
- context = RuntimeEnvironment.application;
+ context = ApplicationProvider.getApplicationContext();
}
@After
diff --git a/robolectric/src/test/java/org/robolectric/RobolectricTestRunnerClassLoaderConfigTest.java b/robolectric/src/test/java/org/robolectric/RobolectricTestRunnerClassLoaderConfigTest.java
index 5961d0a1f..96df76a8c 100644
--- a/robolectric/src/test/java/org/robolectric/RobolectricTestRunnerClassLoaderConfigTest.java
+++ b/robolectric/src/test/java/org/robolectric/RobolectricTestRunnerClassLoaderConfigTest.java
@@ -2,13 +2,14 @@ package org.robolectric;
import static com.google.common.truth.Truth.assertThat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.internal.bytecode.SandboxClassLoader;
import org.robolectric.test.DummyClass;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class RobolectricTestRunnerClassLoaderConfigTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/RobolectricTestRunnerSelfTest.java b/robolectric/src/test/java/org/robolectric/RobolectricTestRunnerSelfTest.java
index e15403223..e6eda5b7a 100644
--- a/robolectric/src/test/java/org/robolectric/RobolectricTestRunnerSelfTest.java
+++ b/robolectric/src/test/java/org/robolectric/RobolectricTestRunnerSelfTest.java
@@ -6,6 +6,8 @@ import static org.junit.Assert.fail;
import android.app.Application;
import android.content.res.Resources;
import android.os.Build;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.hamcrest.CoreMatchers;
import org.junit.AfterClass;
import org.junit.Test;
@@ -13,15 +15,18 @@ import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(application = RobolectricTestRunnerSelfTest.MyTestApplication.class)
public class RobolectricTestRunnerSelfTest {
@Test
public void shouldInitializeAndBindApplicationButNotCallOnCreate() {
- assertThat(RuntimeEnvironment.application).named("application")
+ assertThat((Application) ApplicationProvider.getApplicationContext())
+ .named("application")
.isInstanceOf(MyTestApplication.class);
- assertThat(((MyTestApplication) RuntimeEnvironment.application).onCreateWasCalled).named("onCreate called").isTrue();
+ assertThat(((MyTestApplication) ApplicationProvider.getApplicationContext()).onCreateWasCalled)
+ .named("onCreate called")
+ .isTrue();
if (RuntimeEnvironment.useLegacyResources()) {
assertThat(RuntimeEnvironment.getAppResourceTable())
.named("Application resource loader")
@@ -32,7 +37,7 @@ public class RobolectricTestRunnerSelfTest {
@Test
public void shouldSetUpSystemResources() {
Resources systemResources = Resources.getSystem();
- Resources appResources = RuntimeEnvironment.application.getResources();
+ Resources appResources = ApplicationProvider.getApplicationContext().getResources();
assertThat(systemResources).named("system resources").isNotNull();
diff --git a/robolectric/src/test/java/org/robolectric/TemporaryBindingsTest.java b/robolectric/src/test/java/org/robolectric/TemporaryBindingsTest.java
index b4fedeb13..de5cf7abb 100644
--- a/robolectric/src/test/java/org/robolectric/TemporaryBindingsTest.java
+++ b/robolectric/src/test/java/org/robolectric/TemporaryBindingsTest.java
@@ -5,6 +5,8 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.view.View;
+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.annotation.Config;
@@ -12,20 +14,25 @@ import org.robolectric.annotation.Implements;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowView;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(sdk = O) // running on all SDKs is unnecessary and can cause OOM GC overhead issues
public class TemporaryBindingsTest {
@Test
@Config(shadows = TemporaryShadowView.class)
public void overridingShadowBindingsShouldNotAffectBindingsInLaterTests() throws Exception {
- TemporaryShadowView shadowView = Shadow.extract(new View(RuntimeEnvironment.application));
+ TemporaryShadowView shadowView =
+ Shadow.extract(new View(ApplicationProvider.getApplicationContext()));
assertThat(shadowView.getClass().getSimpleName()).isEqualTo(TemporaryShadowView.class.getSimpleName());
}
@Test
public void overridingShadowBindingsShouldNotAffectBindingsInLaterTestsAgain() throws Exception {
- assertThat(shadowOf(new View(RuntimeEnvironment.application)).getClass().getSimpleName()).isEqualTo(ShadowView.class.getSimpleName());
+ assertThat(
+ shadowOf(new View(ApplicationProvider.getApplicationContext()))
+ .getClass()
+ .getSimpleName())
+ .isEqualTo(ShadowView.class.getSimpleName());
}
@Implements(View.class)
diff --git a/robolectric/src/test/java/org/robolectric/TestRunnerSequenceTest.java b/robolectric/src/test/java/org/robolectric/TestRunnerSequenceTest.java
index ec79166b4..adf29635c 100644
--- a/robolectric/src/test/java/org/robolectric/TestRunnerSequenceTest.java
+++ b/robolectric/src/test/java/org/robolectric/TestRunnerSequenceTest.java
@@ -158,7 +158,6 @@ public class TestRunnerSequenceTest {
return builder.build();
}
- @Override
protected AndroidManifest getAppManifest(Config config) {
return new AndroidManifest(resourceFile("TestAndroidManifest.xml"), resourceFile("res"), resourceFile("assets"));
}
diff --git a/robolectric/src/test/java/org/robolectric/android/AndroidInterceptorsIntegrationTest.java b/robolectric/src/test/java/org/robolectric/android/AndroidInterceptorsIntegrationTest.java
index 63c3dd2b2..164be091e 100644
--- a/robolectric/src/test/java/org/robolectric/android/AndroidInterceptorsIntegrationTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/AndroidInterceptorsIntegrationTest.java
@@ -2,6 +2,7 @@ package org.robolectric.android;
import static com.google.common.truth.Truth.assertThat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.invoke.CallSite;
@@ -12,13 +13,12 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.internal.bytecode.InvokeDynamicSupport;
import org.robolectric.shadows.ShadowSystemClock;
import org.robolectric.util.ReflectionHelpers.ClassParameter;
/** Integration tests for Android interceptors. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class AndroidInterceptorsIntegrationTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/android/AndroidTranslatorClassInstrumentedTest.java b/robolectric/src/test/java/org/robolectric/android/AndroidTranslatorClassInstrumentedTest.java
index e0ca20b41..0ea650bff 100644
--- a/robolectric/src/test/java/org/robolectric/android/AndroidTranslatorClassInstrumentedTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/AndroidTranslatorClassInstrumentedTest.java
@@ -4,15 +4,15 @@ import static com.google.common.truth.Truth.assertThat;
import android.graphics.Bitmap;
import android.graphics.Paint;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.internal.Instrument;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(sdk = Config.NEWEST_SDK)
public class AndroidTranslatorClassInstrumentedTest {
diff --git a/robolectric/src/test/java/org/robolectric/android/BootstrapTest.java b/robolectric/src/test/java/org/robolectric/android/BootstrapTest.java
index 18134803e..81ff41e6a 100644
--- a/robolectric/src/test/java/org/robolectric/android/BootstrapTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/BootstrapTest.java
@@ -47,15 +47,16 @@ import android.os.Build;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.DisplayInfo;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class BootstrapTest {
private Configuration configuration;
@@ -76,8 +77,9 @@ public class BootstrapTest {
@Config(qualifiers = "w480dp-h640dp")
public void shouldSetUpRealisticDisplay() throws Exception {
if (Build.VERSION.SDK_INT > JELLY_BEAN) {
- DisplayManager displayManager = (DisplayManager) RuntimeEnvironment.application
- .getSystemService(Context.DISPLAY_SERVICE);
+ DisplayManager displayManager =
+ (DisplayManager)
+ ApplicationProvider.getApplicationContext().getSystemService(Context.DISPLAY_SERVICE);
DisplayInfo displayInfo = new DisplayInfo();
Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
display.getDisplayInfo(displayInfo);
@@ -100,8 +102,8 @@ public class BootstrapTest {
}
}
- DisplayMetrics displayMetrics = RuntimeEnvironment.application.getResources()
- .getDisplayMetrics();
+ DisplayMetrics displayMetrics =
+ ApplicationProvider.getApplicationContext().getResources().getDisplayMetrics();
assertThat(displayMetrics.widthPixels).isEqualTo(480);
assertThat(displayMetrics.heightPixels).isEqualTo(640);
}
@@ -110,8 +112,9 @@ public class BootstrapTest {
@Config(qualifiers = "w480dp-h640dp-land-hdpi")
public void shouldSetUpRealisticDisplay_landscapeHighDensity() throws Exception {
if (Build.VERSION.SDK_INT > JELLY_BEAN) {
- DisplayManager displayManager = (DisplayManager) RuntimeEnvironment.application
- .getSystemService(Context.DISPLAY_SERVICE);
+ DisplayManager displayManager =
+ (DisplayManager)
+ ApplicationProvider.getApplicationContext().getSystemService(Context.DISPLAY_SERVICE);
DisplayInfo displayInfo = new DisplayInfo();
Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
display.getDisplayInfo(displayInfo);
@@ -134,8 +137,8 @@ public class BootstrapTest {
}
}
- DisplayMetrics displayMetrics = RuntimeEnvironment.application.getResources()
- .getDisplayMetrics();
+ DisplayMetrics displayMetrics =
+ ApplicationProvider.getApplicationContext().getResources().getDisplayMetrics();
assertThat(displayMetrics.widthPixels).isEqualTo(960);
assertThat(displayMetrics.heightPixels).isEqualTo(720);
}
diff --git a/robolectric/src/test/java/org/robolectric/android/DefaultPackageManagerIntentComparatorTest.java b/robolectric/src/test/java/org/robolectric/android/DefaultPackageManagerIntentComparatorTest.java
index 730835257..81bc04c75 100644
--- a/robolectric/src/test/java/org/robolectric/android/DefaultPackageManagerIntentComparatorTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/DefaultPackageManagerIntentComparatorTest.java
@@ -3,12 +3,12 @@ package org.robolectric.android;
import static com.google.common.truth.Truth.assertThat;
import android.content.Intent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowPackageManager.IntentComparator;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class DefaultPackageManagerIntentComparatorTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/android/DeviceConfigTest.java b/robolectric/src/test/java/org/robolectric/android/DeviceConfigTest.java
index 95cb4ca6d..03d2d1942 100644
--- a/robolectric/src/test/java/org/robolectric/android/DeviceConfigTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/DeviceConfigTest.java
@@ -6,16 +6,16 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.res.Configuration;
import android.os.Build.VERSION_CODES;
import android.util.DisplayMetrics;
+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;
import org.robolectric.annotation.Config;
import org.robolectric.res.Qualifiers;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class DeviceConfigTest {
private Configuration configuration;
diff --git a/robolectric/src/test/java/org/robolectric/android/DrawableResourceLoaderTest.java b/robolectric/src/test/java/org/robolectric/android/DrawableResourceLoaderTest.java
index 82983114b..5709a73d1 100644
--- a/robolectric/src/test/java/org/robolectric/android/DrawableResourceLoaderTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/DrawableResourceLoaderTest.java
@@ -17,27 +17,28 @@ import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.NinePatchDrawable;
import android.graphics.drawable.VectorDrawable;
+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.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class DrawableResourceLoaderTest {
private Resources resources;
@Before
public void setup() throws Exception {
assumeTrue(useLegacy());
- resources = RuntimeEnvironment.application.getResources();
+ resources = ApplicationProvider.getApplicationContext().getResources();
}
@Test
public void testGetDrawable_rainbow() throws Exception {
- assertNotNull(RuntimeEnvironment.application.getResources().getDrawable(R.drawable.rainbow));
+ assertNotNull(
+ ApplicationProvider.getApplicationContext().getResources().getDrawable(R.drawable.rainbow));
}
@Test
@@ -71,12 +72,24 @@ public class DrawableResourceLoaderTest {
@Test
@Config(qualifiers = "land")
public void testLayerDrawable_xlarge() {
- assertEquals(6, ((LayerDrawable) RuntimeEnvironment.application.getResources().getDrawable(R.drawable.rainbow)).getNumberOfLayers());
+ assertEquals(
+ 6,
+ ((LayerDrawable)
+ ApplicationProvider.getApplicationContext()
+ .getResources()
+ .getDrawable(R.drawable.rainbow))
+ .getNumberOfLayers());
}
@Test
public void testLayerDrawable() {
- assertEquals(8, ((LayerDrawable) RuntimeEnvironment.application.getResources().getDrawable(R.drawable.rainbow)).getNumberOfLayers());
+ assertEquals(
+ 8,
+ ((LayerDrawable)
+ ApplicationProvider.getApplicationContext()
+ .getResources()
+ .getDrawable(R.drawable.rainbow))
+ .getNumberOfLayers());
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/android/FragmentTestUtilTest.java b/robolectric/src/test/java/org/robolectric/android/FragmentTestUtilTest.java
index 326e3e476..9512c5f71 100644
--- a/robolectric/src/test/java/org/robolectric/android/FragmentTestUtilTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/FragmentTestUtilTest.java
@@ -12,12 +12,12 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class FragmentTestUtilTest {
@Test
public void startFragment_shouldStartFragment() {
diff --git a/robolectric/src/test/java/org/robolectric/android/PreferenceIntegrationTest.java b/robolectric/src/test/java/org/robolectric/android/PreferenceIntegrationTest.java
index 803e852d4..34cc01416 100644
--- a/robolectric/src/test/java/org/robolectric/android/PreferenceIntegrationTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/PreferenceIntegrationTest.java
@@ -14,13 +14,13 @@ import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
import android.preference.RingtonePreference;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class PreferenceIntegrationTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/android/ResourceLoaderTest.java b/robolectric/src/test/java/org/robolectric/android/ResourceLoaderTest.java
index 2cbebe548..129aa5717 100644
--- a/robolectric/src/test/java/org/robolectric/android/ResourceLoaderTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/ResourceLoaderTest.java
@@ -12,19 +12,20 @@ import android.os.Build.VERSION_CODES;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.res.ResName;
import org.robolectric.res.ResourceTable;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ResourceLoaderTest {
private String optsForO;
@@ -41,13 +42,21 @@ public class ResourceLoaderTest {
@Test
@Config(qualifiers="w0dp")
public void checkDefaultBooleanValue() throws Exception {
- assertThat(RuntimeEnvironment.application.getResources().getBoolean(R.bool.different_resource_boolean)).isEqualTo(false);
+ assertThat(
+ ApplicationProvider.getApplicationContext()
+ .getResources()
+ .getBoolean(R.bool.different_resource_boolean))
+ .isEqualTo(false);
}
@Test
@Config(qualifiers="w820dp")
public void checkQualifiedBooleanValue() throws Exception {
- assertThat(RuntimeEnvironment.application.getResources().getBoolean(R.bool.different_resource_boolean)).isEqualTo(true);
+ assertThat(
+ ApplicationProvider.getApplicationContext()
+ .getResources()
+ .getBoolean(R.bool.different_resource_boolean))
+ .isEqualTo(true);
}
@Test
@@ -64,7 +73,9 @@ public class ResourceLoaderTest {
assertThat(RuntimeEnvironment.getQualifiers())
.isEqualTo("en-rUS-ldltr-sw320dp-w320dp-h470dp-normal-notlong-notround-" + optsForO + "port-notnight-mdpi-finger-keyssoft-nokeys-navhidden-nonav-v" + Build.VERSION.RESOURCES_SDK_INT);
- View view = LayoutInflater.from(RuntimeEnvironment.application).inflate(R.layout.different_screen_sizes, null);
+ View view =
+ LayoutInflater.from(ApplicationProvider.getApplicationContext())
+ .inflate(R.layout.different_screen_sizes, null);
TextView textView = view.findViewById(android.R.id.text1);
assertThat(textView.getText().toString()).isEqualTo("default");
RuntimeEnvironment.setQualifiers("fr-land"); // testing if this pollutes the other test
@@ -91,6 +102,7 @@ public class ResourceLoaderTest {
internalResourceId = (Integer) internalRIdClass.getDeclaredField(internalResource.name).get(null);
assertThat(resId).isEqualTo(internalResourceId);
- assertThat(RuntimeEnvironment.application.getResources().getString(resId)).isEqualTo("The old PIN you typed isn't correct.");
+ assertThat(ApplicationProvider.getApplicationContext().getResources().getString(resId))
+ .isEqualTo("The old PIN you typed isn't correct.");
}
}
diff --git a/robolectric/src/test/java/org/robolectric/android/ResourceTableFactoryIntegrationTest.java b/robolectric/src/test/java/org/robolectric/android/ResourceTableFactoryIntegrationTest.java
index ceb4f84cf..65b523ad4 100644
--- a/robolectric/src/test/java/org/robolectric/android/ResourceTableFactoryIntegrationTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/ResourceTableFactoryIntegrationTest.java
@@ -5,14 +5,14 @@ import static org.junit.Assume.assumeTrue;
import static org.robolectric.shadows.ShadowAssetManager.useLegacy;
import android.os.Build;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.res.ResName;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = Build.VERSION_CODES.L)
public class ResourceTableFactoryIntegrationTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/android/ShadowingTest.java b/robolectric/src/test/java/org/robolectric/android/ShadowingTest.java
index ba76b21e2..41b91a819 100644
--- a/robolectric/src/test/java/org/robolectric/android/ShadowingTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/ShadowingTest.java
@@ -4,15 +4,16 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import android.app.Application;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
+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 ShadowingTest {
@Test
@@ -22,17 +23,19 @@ public class ShadowingTest {
@Test
public void shouldDelegateToObjectToStringIfShadowHasNone() throws Exception {
- assertThat(new Toast(RuntimeEnvironment.application).toString()).startsWith("android.widget.Toast@");
+ assertThat(new Toast((Application) ApplicationProvider.getApplicationContext()).toString())
+ .startsWith("android.widget.Toast@");
}
@Test
public void shouldDelegateToObjectHashCodeIfShadowHasNone() throws Exception {
- assertFalse(new View(RuntimeEnvironment.application).hashCode() == 0);
+ assertFalse(
+ new View((Application) ApplicationProvider.getApplicationContext()).hashCode() == 0);
}
@Test
public void shouldDelegateToObjectEqualsIfShadowHasNone() throws Exception {
- View view = new View(RuntimeEnvironment.application);
+ View view = new View((Application) ApplicationProvider.getApplicationContext());
assertEquals(view, view);
}
}
diff --git a/robolectric/src/test/java/org/robolectric/android/XmlResourceParserImplTest.java b/robolectric/src/test/java/org/robolectric/android/XmlResourceParserImplTest.java
index cbd887df2..5f930af8d 100644
--- a/robolectric/src/test/java/org/robolectric/android/XmlResourceParserImplTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/XmlResourceParserImplTest.java
@@ -7,7 +7,10 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
+import android.app.Application;
import android.content.res.XmlResourceParser;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -24,13 +27,12 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.w3c.dom.Document;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class XmlResourceParserImplTest {
private static final String RES_AUTO_NS = "http://schemas.android.com/apk/res-auto";
@@ -38,7 +40,10 @@ public class XmlResourceParserImplTest {
@Before
public void setUp() throws Exception {
- parser = RuntimeEnvironment.application.getResources().getXml(R.xml.preferences);
+ parser =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getXml(R.xml.preferences);
}
@After
@@ -573,7 +578,10 @@ public class XmlResourceParserImplTest {
@Test
public void testGetAttributeResourceValueIntInt() throws Exception {
- parser = RuntimeEnvironment.application.getResources().getXml(R.xml.has_attribute_resource_value);
+ parser =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getXml(R.xml.has_attribute_resource_value);
parseUntilNext(XmlResourceParser.START_TAG);
assertThat(parser.getAttributeResourceValue(0, 42)).isEqualTo(R.layout.main);
@@ -581,7 +589,10 @@ public class XmlResourceParserImplTest {
@Test
public void testGetAttributeResourceValueStringStringInt() throws Exception {
- parser = RuntimeEnvironment.application.getResources().getXml(R.xml.has_attribute_resource_value);
+ parser =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getXml(R.xml.has_attribute_resource_value);
parseUntilNext(XmlResourceParser.START_TAG);
assertThat(parser.getAttributeResourceValue(RES_AUTO_NS, "bar", 42)).isEqualTo(R.layout.main);
@@ -705,7 +716,10 @@ public class XmlResourceParserImplTest {
public void testGetIdAttributeResourceValue_defaultValue() throws Exception {
assertThat(parser.getIdAttributeResourceValue(12)).isEqualTo(12);
- parser = RuntimeEnvironment.application.getResources().getXml(R.xml.has_id);
+ parser =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getXml(R.xml.has_id);
parseUntilNext(XmlResourceParser.START_TAG);
assertThat(parser.getIdAttributeResourceValue(12)).isEqualTo(R.id.tacos);
}
@@ -718,14 +732,20 @@ public class XmlResourceParserImplTest {
@Test
public void getStyleAttribute_allowStyleAttrReference() throws Exception {
- parser = RuntimeEnvironment.application.getResources().getXml(R.xml.has_style_attribute_reference);
+ parser =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getXml(R.xml.has_style_attribute_reference);
parseUntilNext(XmlResourceParser.START_TAG);
assertThat(parser.getStyleAttribute()).isEqualTo(R.attr.parentStyleReference);
}
@Test
public void getStyleAttribute_allowStyleAttrReferenceLackingExplicitAttrType() throws Exception {
- parser = RuntimeEnvironment.application.getResources().getXml(R.xml.has_parent_style_reference);
+ parser =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getXml(R.xml.has_parent_style_reference);
parseUntilNext(XmlResourceParser.START_TAG);
assertThat(parser.getStyleAttribute()).isEqualTo(R.attr.parentStyleReference);
}
diff --git a/robolectric/src/test/java/org/robolectric/android/controller/ActivityControllerTest.java b/robolectric/src/test/java/org/robolectric/android/controller/ActivityControllerTest.java
index 99907d772..ea4375763 100644
--- a/robolectric/src/test/java/org/robolectric/android/controller/ActivityControllerTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/controller/ActivityControllerTest.java
@@ -16,6 +16,8 @@ import android.view.ContextThemeWrapper;
import android.view.ViewRootImpl;
import android.view.Window;
import android.widget.LinearLayout;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
@@ -23,14 +25,13 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLooper;
import org.robolectric.util.Scheduler;
import org.robolectric.util.TestRunnable;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ActivityControllerTest {
private static final List<String> transcript = new ArrayList<>();
private final ComponentName componentName = new ComponentName("org.robolectric", MyActivity.class.getName());
@@ -220,7 +221,9 @@ public class ActivityControllerTest {
@Test
public void configurationChange_callsLifecycleMethodsAndAppliesConfig() {
- Configuration config = new Configuration(RuntimeEnvironment.application.getResources().getConfiguration());
+ Configuration config =
+ new Configuration(
+ ApplicationProvider.getApplicationContext().getResources().getConfiguration());
final float newFontScale = config.fontScale *= 2;
controller.setup();
@@ -232,7 +235,9 @@ public class ActivityControllerTest {
@Test
public void configurationChange_callsOnConfigurationChangedAndAppliesConfigWhenAllManaged() {
- Configuration config = new Configuration(RuntimeEnvironment.application.getResources().getConfiguration());
+ Configuration config =
+ new Configuration(
+ ApplicationProvider.getApplicationContext().getResources().getConfiguration());
final float newFontScale = config.fontScale *= 2;
ActivityController<ConfigAwareActivity> configController =
@@ -245,7 +250,9 @@ public class ActivityControllerTest {
@Test
public void configurationChange_callsLifecycleMethodsAndAppliesConfigWhenAnyNonManaged() {
- Configuration config = new Configuration(RuntimeEnvironment.application.getResources().getConfiguration());
+ Configuration config =
+ new Configuration(
+ ApplicationProvider.getApplicationContext().getResources().getConfiguration());
final float newFontScale = config.fontScale *= 2;
final int newOrientation = config.orientation = (config.orientation + 1) % 3;
@@ -272,7 +279,9 @@ public class ActivityControllerTest {
@Test
@Config(qualifiers = "land")
public void configurationChange_restoresTheme() {
- Configuration config = new Configuration(RuntimeEnvironment.application.getResources().getConfiguration());
+ Configuration config =
+ new Configuration(
+ ApplicationProvider.getApplicationContext().getResources().getConfiguration());
config.orientation = Configuration.ORIENTATION_PORTRAIT;
controller.get().setTheme(android.R.style.Theme_Black);
@@ -286,7 +295,9 @@ public class ActivityControllerTest {
@Test
@Config(qualifiers = "land")
public void configurationChange_reattachesRetainedFragments() {
- Configuration config = new Configuration(RuntimeEnvironment.application.getResources().getConfiguration());
+ Configuration config =
+ new Configuration(
+ ApplicationProvider.getApplicationContext().getResources().getConfiguration());
config.orientation = Configuration.ORIENTATION_PORTRAIT;
ActivityController<NonConfigStateActivity> configController =
@@ -329,7 +340,7 @@ public class ActivityControllerTest {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
- setContentView(new LinearLayout(RuntimeEnvironment.application));
+ setContentView(new LinearLayout(ApplicationProvider.getApplicationContext()));
transcribeWhilePaused("onCreate");
transcript.add("finishedOnCreate");
}
diff --git a/robolectric/src/test/java/org/robolectric/android/controller/BackupAgentControllerTest.java b/robolectric/src/test/java/org/robolectric/android/controller/BackupAgentControllerTest.java
index 313fc20c0..6b90ea93b 100644
--- a/robolectric/src/test/java/org/robolectric/android/controller/BackupAgentControllerTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/controller/BackupAgentControllerTest.java
@@ -2,25 +2,27 @@ package org.robolectric.android.controller;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.os.ParcelFileDescriptor;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class BackupAgentControllerTest {
private final BackupAgentController<MyBackupAgent> backupAgentController = Robolectric.buildBackupAgent(MyBackupAgent.class);
@Test
public void shouldSetBaseContext() throws Exception {
MyBackupAgent myBackupAgent = backupAgentController.get();
- assertThat(myBackupAgent.getBaseContext()).isEqualTo(RuntimeEnvironment.application.getBaseContext());
+ assertThat(myBackupAgent.getBaseContext())
+ .isEqualTo(((Application) ApplicationProvider.getApplicationContext()).getBaseContext());
}
public static class MyBackupAgent extends BackupAgent {
diff --git a/robolectric/src/test/java/org/robolectric/android/controller/ContentProviderControllerTest.java b/robolectric/src/test/java/org/robolectric/android/controller/ContentProviderControllerTest.java
index fecc62f78..190e8878a 100644
--- a/robolectric/src/test/java/org/robolectric/android/controller/ContentProviderControllerTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/controller/ContentProviderControllerTest.java
@@ -2,33 +2,35 @@ package org.robolectric.android.controller;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
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.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.testing.TestContentProvider1;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ContentProviderControllerTest {
private final ContentProviderController<TestContentProvider1> controller = Robolectric.buildContentProvider(TestContentProvider1.class);
private ContentResolver contentResolver;
@Before
public void setUp() throws Exception {
- contentResolver = RuntimeEnvironment.application.getContentResolver();
+ contentResolver = ApplicationProvider.getApplicationContext().getContentResolver();
}
@Test
public void shouldSetBaseContext() throws Exception {
TestContentProvider1 myContentProvider = controller.create().get();
- assertThat(myContentProvider.getContext()).isEqualTo(RuntimeEnvironment.application.getBaseContext());
+ assertThat(myContentProvider.getContext())
+ .isEqualTo(((Application) ApplicationProvider.getApplicationContext()).getBaseContext());
}
@Test
@@ -100,8 +102,10 @@ public class ContentProviderControllerTest {
static class XContentProvider extends TestContentProvider1 {
@Override
public boolean onCreate() {
- ContentProviderClient contentProviderClient = RuntimeEnvironment.application.getContentResolver()
- .acquireContentProviderClient("x-authority");
+ ContentProviderClient contentProviderClient =
+ ApplicationProvider.getApplicationContext()
+ .getContentResolver()
+ .acquireContentProviderClient("x-authority");
transcript.add(contentProviderClient == null ? "x-authority not registered yet" : "x-authority is registered");
return false;
}
diff --git a/robolectric/src/test/java/org/robolectric/android/controller/FragmentControllerTest.java b/robolectric/src/test/java/org/robolectric/android/controller/FragmentControllerTest.java
index 5a9b8abd6..b23e522ca 100644
--- a/robolectric/src/test/java/org/robolectric/android/controller/FragmentControllerTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/controller/FragmentControllerTest.java
@@ -13,12 +13,12 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class FragmentControllerTest {
private static final int VIEW_ID_CUSTOMIZED_LOGIN_ACTIVITY = 123;
diff --git a/robolectric/src/test/java/org/robolectric/android/controller/IntentServiceControllerTest.java b/robolectric/src/test/java/org/robolectric/android/controller/IntentServiceControllerTest.java
index 5096b7985..67115f8ba 100644
--- a/robolectric/src/test/java/org/robolectric/android/controller/IntentServiceControllerTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/controller/IntentServiceControllerTest.java
@@ -9,16 +9,16 @@ import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowLooper;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class IntentServiceControllerTest {
private static final List<String> transcript = new ArrayList<>();
private final ComponentName componentName = new ComponentName("org.robolectric", MyService.class.getName());
diff --git a/robolectric/src/test/java/org/robolectric/android/controller/ServiceControllerTest.java b/robolectric/src/test/java/org/robolectric/android/controller/ServiceControllerTest.java
index 0e919a9cb..e86258f19 100644
--- a/robolectric/src/test/java/org/robolectric/android/controller/ServiceControllerTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/controller/ServiceControllerTest.java
@@ -9,16 +9,16 @@ import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowLooper;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ServiceControllerTest {
private static final List<String> transcript = new ArrayList<>();
private final ComponentName componentName = new ComponentName("org.robolectric", MyService.class.getName());
@@ -112,14 +112,14 @@ public class ServiceControllerTest {
private Handler handler = new Handler(Looper.getMainLooper());
public Intent boundIntent;
-
+
public Intent reboundIntent;
public Intent startIntent;
public int startFlags;
public int startId;
-
+
public Intent unboundIntent;
-
+
@Override
public IBinder onBind(Intent intent) {
boundIntent = intent;
diff --git a/robolectric/src/test/java/org/robolectric/android/internal/ParallelUniverseCreateApplicationTest.java b/robolectric/src/test/java/org/robolectric/android/internal/ParallelUniverseCreateApplicationTest.java
index c49d82d8a..7cc24beef 100644
--- a/robolectric/src/test/java/org/robolectric/android/internal/ParallelUniverseCreateApplicationTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/internal/ParallelUniverseCreateApplicationTest.java
@@ -5,6 +5,8 @@ import static org.robolectric.Shadows.shadowOf;
import static org.robolectric.android.internal.ParallelUniverse.registerBroadcastReceivers;
import android.app.Application;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import java.io.File;
@@ -15,7 +17,6 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.robolectric.FakeApp;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.TestFakeApp;
import org.robolectric.annotation.Config;
@@ -24,7 +25,7 @@ import org.robolectric.res.Fs;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.testing.TestApplication;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ParallelUniverseCreateApplicationTest {
@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
@@ -49,7 +50,7 @@ public class ParallelUniverseCreateApplicationTest {
}
@Test public void shouldAssignThePackageNameFromTheManifest() throws Exception {
- Application application = RuntimeEnvironment.application;
+ Application application = ApplicationProvider.getApplicationContext();
assertThat(application.getPackageName()).isEqualTo("org.robolectric");
assertThat(application).isInstanceOf(TestApplication.class);
@@ -58,7 +59,9 @@ public class ParallelUniverseCreateApplicationTest {
@Test
public void shouldRegisterReceiversFromTheManifest() throws Exception {
// gross:
- shadowOf(RuntimeEnvironment.application).getRegisteredReceivers().clear();
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .getRegisteredReceivers()
+ .clear();
AndroidManifest appManifest = newConfigWith(
"<application>"
diff --git a/robolectric/src/test/java/org/robolectric/android/internal/ParallelUniverseTest.java b/robolectric/src/test/java/org/robolectric/android/internal/ParallelUniverseTest.java
index c5d9e46b1..db1a46b9a 100644
--- a/robolectric/src/test/java/org/robolectric/android/internal/ParallelUniverseTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/internal/ParallelUniverseTest.java
@@ -11,6 +11,7 @@ import android.app.Application;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
+import androidx.test.core.app.ApplicationProvider;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Locale;
@@ -61,7 +62,8 @@ public class ParallelUniverseTest {
RoboSettings.setUseGlobalScheduler(true);
try {
bootstrapWrapper.callSetUpApplicationState();
- final ShadowApplication shadowApplication = Shadow.extract(RuntimeEnvironment.application);
+ final ShadowApplication shadowApplication =
+ Shadow.extract(ApplicationProvider.getApplicationContext());
assertThat(shadowApplication.getBackgroundThreadScheduler())
.isSameAs(shadowApplication.getForegroundThreadScheduler());
assertThat(RuntimeEnvironment.getMasterScheduler())
@@ -74,7 +76,8 @@ public class ParallelUniverseTest {
@Test
public void setUpApplicationState_setsBackgroundScheduler_toBeDifferentToForeground_byDefault() {
bootstrapWrapper.callSetUpApplicationState();
- final ShadowApplication shadowApplication = Shadow.extract(RuntimeEnvironment.application);
+ final ShadowApplication shadowApplication =
+ Shadow.extract(ApplicationProvider.getApplicationContext());
assertThat(shadowApplication.getBackgroundThreadScheduler())
.isNotSameAs(shadowApplication.getForegroundThreadScheduler());
}
diff --git a/robolectric/src/test/java/org/robolectric/android/util/concurrent/RoboExecutorServiceTest.java b/robolectric/src/test/java/org/robolectric/android/util/concurrent/RoboExecutorServiceTest.java
index bab7e16a2..b31609947 100644
--- a/robolectric/src/test/java/org/robolectric/android/util/concurrent/RoboExecutorServiceTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/util/concurrent/RoboExecutorServiceTest.java
@@ -2,6 +2,7 @@ package org.robolectric.android.util.concurrent;
import static com.google.common.truth.Truth.assertThat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
@@ -11,11 +12,10 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.Scheduler;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class RoboExecutorServiceTest {
private final List<String> transcript = new ArrayList<>();
private final RoboExecutorService executorService = new RoboExecutorService();
diff --git a/robolectric/src/test/java/org/robolectric/fakes/RoboCursorTest.java b/robolectric/src/test/java/org/robolectric/fakes/RoboCursorTest.java
index bdde6e3e2..ba57971cf 100644
--- a/robolectric/src/test/java/org/robolectric/fakes/RoboCursorTest.java
+++ b/robolectric/src/test/java/org/robolectric/fakes/RoboCursorTest.java
@@ -8,13 +8,13 @@ import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
+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 RoboCursorTest {
private static final String STRING_COLUMN = "stringColumn";
private static final String LONG_COLUMN = "longColumn";
@@ -31,7 +31,7 @@ public class RoboCursorTest {
@Before
public void setup() throws Exception {
- contentResolver = RuntimeEnvironment.application.getContentResolver();
+ contentResolver = ApplicationProvider.getApplicationContext().getContentResolver();
shadowOf(contentResolver).setCursor(uri, cursor);
cursor.setColumnNames(asList(
@@ -112,7 +112,7 @@ public class RoboCursorTest {
@Test
public void get_shouldConvert() throws Exception {
cursor.setResults(new Object[][]{new Object[]{
- "aString", 1234L, "42", new byte[]{1, 2, 3}, 255, "1.25", 2.5d, null
+ "aString", "1234", "42", new byte[]{1, 2, 3}, 255, "1.25", 2.5d, null
}});
assertThat(cursor.getCount()).isEqualTo(1);
assertThat(cursor.moveToNext()).isTrue();
diff --git a/robolectric/src/test/java/org/robolectric/fakes/RoboMenuItemTest.java b/robolectric/src/test/java/org/robolectric/fakes/RoboMenuItemTest.java
index 8fda1b943..e086ffed5 100644
--- a/robolectric/src/test/java/org/robolectric/fakes/RoboMenuItemTest.java
+++ b/robolectric/src/test/java/org/robolectric/fakes/RoboMenuItemTest.java
@@ -3,24 +3,25 @@ package org.robolectric.fakes;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.graphics.drawable.Drawable;
import android.view.MenuItem;
import android.view.View;
+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.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class RoboMenuItemTest {
private MenuItem item;
private TestOnActionExpandListener listener;
@Before
public void setUp() throws Exception {
- item = new RoboMenuItem(RuntimeEnvironment.application);
+ item = new RoboMenuItem((Application) ApplicationProvider.getApplicationContext());
listener = new TestOnActionExpandListener();
item.setOnActionExpandListener(listener);
}
@@ -54,14 +55,14 @@ public class RoboMenuItemTest {
@Test
public void expandActionView_shouldSetExpandedTrue() throws Exception {
- item.setActionView(new View(RuntimeEnvironment.application));
+ item.setActionView(new View((Application) ApplicationProvider.getApplicationContext()));
assertThat(item.expandActionView()).isTrue();
assertThat(item.isActionViewExpanded()).isTrue();
}
@Test
public void expandActionView_shouldInvokeListener() throws Exception {
- item.setActionView(new View(RuntimeEnvironment.application));
+ item.setActionView(new View((Application) ApplicationProvider.getApplicationContext()));
item.expandActionView();
assertThat(listener.expanded).isTrue();
}
@@ -74,7 +75,7 @@ public class RoboMenuItemTest {
@Test
public void collapseActionView_shouldSetExpandedFalse() throws Exception {
- item.setActionView(new View(RuntimeEnvironment.application));
+ item.setActionView(new View((Application) ApplicationProvider.getApplicationContext()));
item.expandActionView();
assertThat(item.collapseActionView()).isTrue();
assertThat(item.isActionViewExpanded()).isFalse();
@@ -82,7 +83,7 @@ public class RoboMenuItemTest {
@Test
public void collapseActionView_shouldInvokeListener() throws Exception {
- item.setActionView(new View(RuntimeEnvironment.application));
+ item.setActionView(new View((Application) ApplicationProvider.getApplicationContext()));
listener.expanded = true;
item.collapseActionView();
assertThat(listener.expanded).isFalse();
@@ -141,7 +142,10 @@ public class RoboMenuItemTest {
@Test
public void getIcon_shouldReturnDrawableFromSetIconDrawable() throws Exception {
- Drawable testDrawable = RuntimeEnvironment.application.getResources().getDrawable(R.drawable.an_image);
+ Drawable testDrawable =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getDrawable(R.drawable.an_image);
assertThat(testDrawable).isNotNull();
assertThat(item.getIcon()).isNull();
item.setIcon(testDrawable);
diff --git a/robolectric/src/test/java/org/robolectric/fakes/RoboMenuTest.java b/robolectric/src/test/java/org/robolectric/fakes/RoboMenuTest.java
index 712fb9a4c..36af367ea 100644
--- a/robolectric/src/test/java/org/robolectric/fakes/RoboMenuTest.java
+++ b/robolectric/src/test/java/org/robolectric/fakes/RoboMenuTest.java
@@ -5,22 +5,23 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import android.app.Activity;
+import android.app.Application;
import android.content.Intent;
import android.view.MenuItem;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class RoboMenuTest {
@Test
public void addAndRemoveMenuItems() {
- RoboMenu menu = new RoboMenu(RuntimeEnvironment.application);
+ RoboMenu menu = new RoboMenu((Application) ApplicationProvider.getApplicationContext());
menu.add(9, 10, 0, org.robolectric.R.string.ok);
RoboMenuItem item = (RoboMenuItem) menu.findItem(10);
@@ -36,7 +37,7 @@ public class RoboMenuTest {
@Test
public void addSubMenu() {
- RoboMenu menu = new RoboMenu(RuntimeEnvironment.application);
+ RoboMenu menu = new RoboMenu((Application) ApplicationProvider.getApplicationContext());
menu.addSubMenu(9, 10, 0, org.robolectric.R.string.ok);
RoboMenuItem item = (RoboMenuItem) menu.findItem(10);
@@ -66,7 +67,7 @@ public class RoboMenuTest {
@Test
public void add_AddsItemsInOrder() {
- RoboMenu menu = new RoboMenu(RuntimeEnvironment.application);
+ RoboMenu menu = new RoboMenu((Application) ApplicationProvider.getApplicationContext());
menu.add(0, 0, 1, "greeting");
menu.add(0, 0, 0, "hell0");
menu.add(0, 0, 0, "hello");
diff --git a/robolectric/src/test/java/org/robolectric/fakes/RoboWebSettingsTest.java b/robolectric/src/test/java/org/robolectric/fakes/RoboWebSettingsTest.java
index 9179ecd97..0f76fbcd2 100644
--- a/robolectric/src/test/java/org/robolectric/fakes/RoboWebSettingsTest.java
+++ b/robolectric/src/test/java/org/robolectric/fakes/RoboWebSettingsTest.java
@@ -3,13 +3,13 @@ package org.robolectric.fakes;
import static com.google.common.truth.Truth.assertThat;
import android.webkit.WebSettings;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.internal.DoNotInstrument;
@DoNotInstrument
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class RoboWebSettingsTest {
private final RoboWebSettings webSettings = new RoboWebSettings();
private static final boolean[] TRUE_AND_FALSE = {true, false};
diff --git a/robolectric/src/test/java/org/robolectric/internal/DefaultManifestFactoryTest.java b/robolectric/src/test/java/org/robolectric/internal/DefaultManifestFactoryTest.java
index 8b2e6615b..8c6465a14 100644
--- a/robolectric/src/test/java/org/robolectric/internal/DefaultManifestFactoryTest.java
+++ b/robolectric/src/test/java/org/robolectric/internal/DefaultManifestFactoryTest.java
@@ -137,4 +137,4 @@ public class DefaultManifestFactoryTest {
assertThat(manifest.getRClassName())
.isEqualTo("overridden.package.R");
}
-}
+} \ No newline at end of file
diff --git a/robolectric/src/test/java/org/robolectric/internal/dependency/MavenDependencyResolverTest.java b/robolectric/src/test/java/org/robolectric/internal/dependency/MavenDependencyResolverTest.java
index 788e83b72..ec47cdebb 100644
--- a/robolectric/src/test/java/org/robolectric/internal/dependency/MavenDependencyResolverTest.java
+++ b/robolectric/src/test/java/org/robolectric/internal/dependency/MavenDependencyResolverTest.java
@@ -28,6 +28,10 @@ public class MavenDependencyResolverTest {
private static final String REPOSITORY_ID = "remote";
+ private static final String REPOSITORY_USERNAME = "username";
+
+ private static final String REPOSITORY_PASSWORD = "password";
+
private DependenciesTask dependenciesTask;
private Project project;
@@ -114,7 +118,7 @@ public class MavenDependencyResolverTest {
}
private DependencyResolver createResolver() {
- return new MavenDependencyResolver(REPOSITORY_URL, REPOSITORY_ID) {
+ return new MavenDependencyResolver(REPOSITORY_URL, REPOSITORY_ID, REPOSITORY_USERNAME, REPOSITORY_PASSWORD) {
@Override
protected DependenciesTask createDependenciesTask() {
return dependenciesTask;
diff --git a/robolectric/src/test/java/org/robolectric/json/JSONArrayTest.java b/robolectric/src/test/java/org/robolectric/json/JSONArrayTest.java
index 7d4ffed63..d6df95a30 100644
--- a/robolectric/src/test/java/org/robolectric/json/JSONArrayTest.java
+++ b/robolectric/src/test/java/org/robolectric/json/JSONArrayTest.java
@@ -2,13 +2,13 @@ package org.robolectric.json;
import static com.google.common.truth.Truth.assertThat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Arrays;
import org.json.JSONArray;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class JSONArrayTest {
@Test
public void testEquality() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/junit/rules/ExpectedLogMessagesRuleTest.java b/robolectric/src/test/java/org/robolectric/junit/rules/ExpectedLogMessagesRuleTest.java
index 5905ac97b..b642f7909 100644
--- a/robolectric/src/test/java/org/robolectric/junit/rules/ExpectedLogMessagesRuleTest.java
+++ b/robolectric/src/test/java/org/robolectric/junit/rules/ExpectedLogMessagesRuleTest.java
@@ -1,15 +1,15 @@
package org.robolectric.junit.rules;
import android.util.Log;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
/** Tests for {@link ExpectedLogMessagesRule}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public final class ExpectedLogMessagesRuleTest {
private ExpectedLogMessagesRule rule = new ExpectedLogMessagesRule();
diff --git a/robolectric/src/test/java/org/robolectric/manifest/AndroidManifestTest.java b/robolectric/src/test/java/org/robolectric/manifest/AndroidManifestTest.java
index 398e889c1..80ed5339e 100644
--- a/robolectric/src/test/java/org/robolectric/manifest/AndroidManifestTest.java
+++ b/robolectric/src/test/java/org/robolectric/manifest/AndroidManifestTest.java
@@ -35,10 +35,12 @@ public class AndroidManifestTest {
assertThat(config.getContentProviders().get(0).getName())
.isEqualTo("org.robolectric.tester.FullyQualifiedClassName");
assertThat(config.getContentProviders().get(0).getAuthorities()).isEqualTo("org.robolectric.authority1");
+ assertThat(config.getContentProviders().get(0).isEnabled()).isTrue();
assertThat(config.getContentProviders().get(1).getName())
.isEqualTo("org.robolectric.tester.PartiallyQualifiedClassName");
assertThat(config.getContentProviders().get(1).getAuthorities()).isEqualTo("org.robolectric.authority2");
+ assertThat(config.getContentProviders().get(1).isEnabled()).isFalse();
}
@Test
@@ -92,6 +94,7 @@ public class AndroidManifestTest {
assertThat(config.getBroadcastReceivers().get(4).getName())
.isEqualTo("org.robolectric.test.ConfigTestReceiver");
assertThat(config.getBroadcastReceivers().get(4).getActions()).contains("org.robolectric.ACTION_DOT_SUBPACKAGE");
+ assertThat(config.getBroadcastReceivers().get(4).isEnabled()).isFalse();
assertThat(config.getBroadcastReceivers().get(5).getName()).isEqualTo("com.foo.Receiver");
assertThat(config.getBroadcastReceivers().get(5).getActions()).contains("org.robolectric.ACTION_DIFFERENT_PACKAGE");
@@ -126,6 +129,9 @@ public class AndroidManifestTest {
assertThat(config.getServiceData("com.bar.ServiceWithoutIntentFilter").getClassName()).isEqualTo("com.bar.ServiceWithoutIntentFilter");
assertThat(config.getServiceData("com.foo.Service").getPermission())
.isEqualTo("com.foo.Permission");
+
+ assertThat(config.getServiceData("com.foo.Service").isEnabled()).isTrue();
+ assertThat(config.getServiceData("com.bar.ServiceWithoutIntentFilter").isEnabled()).isFalse();
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/res/ResourceParserTest.java b/robolectric/src/test/java/org/robolectric/res/ResourceParserTest.java
index b92c18e71..7b5d59ebe 100644
--- a/robolectric/src/test/java/org/robolectric/res/ResourceParserTest.java
+++ b/robolectric/src/test/java/org/robolectric/res/ResourceParserTest.java
@@ -22,9 +22,8 @@ public class ResourceParserTest {
config = new ResTable_config();
}
-
@Test
- public void shouldLoadDrawableXmlResources() throws Exception {
+ public void shouldLoadDrawableXmlResources() {
TypedResource value = resourceTable.getValue(new ResName("org.robolectric", "drawable", "rainbow"), config);
assertThat(value).isNotNull();
assertThat(value.getResType()).isEqualTo(ResType.DRAWABLE);
@@ -33,7 +32,7 @@ public class ResourceParserTest {
}
@Test
- public void shouldLoadDrawableBitmapResources() throws Exception {
+ public void shouldLoadDrawableBitmapResources() {
TypedResource value = resourceTable.getValue(new ResName("org.robolectric", "drawable", "an_image"), config);
assertThat(value).isNotNull();
assertThat(value.getResType()).isEqualTo(ResType.DRAWABLE);
@@ -42,7 +41,7 @@ public class ResourceParserTest {
}
@Test
- public void shouldLoadDrawableBitmapResourcesDefinedByItemTag() throws Exception {
+ public void shouldLoadDrawableBitmapResourcesDefinedByItemTag() {
TypedResource value = resourceTable.getValue(new ResName("org.robolectric", "drawable", "example_item_drawable"), config);
assertThat(value).isNotNull();
assertThat(value.getResType()).isEqualTo(ResType.DRAWABLE);
@@ -51,18 +50,20 @@ public class ResourceParserTest {
}
@Test
- public void shouldLoadIdResourcesDefinedByItemTag() throws Exception {
+ public void shouldLoadIdResourcesDefinedByItemTag() {
TypedResource value = resourceTable.getValue(new ResName("org.robolectric", "id", "id_declared_in_item_tag"), config);
assertThat(value).isNotNull();
assertThat(value.getResType()).isEqualTo(ResType.CHAR_SEQUENCE);
assertThat(value.isReference()).isFalse();
- assertThat(value.asString()).isEqualTo("");
- assertThat((String) value.getData()).isEqualTo("");
+ assertThat(value.asString()).isEmpty();
+ assertThat((String) value.getData()).isEmpty();
}
@Test
- public void whenIdItemsHaveStringContent_shouldLoadIdResourcesDefinedByItemTag() throws Exception {
- TypedResource value2 = resourceTable.getValue(new ResName("org.robolectric", "id", "id_with_string_value"), config);
- assertThat(value2.asString()).isEqualTo("string value");
+ public void whenIdItemsHaveStringContent_shouldLoadIdResourcesDefinedByItemTag() {
+ TypedResource value =
+ resourceTable.getValue(
+ new ResName("org.robolectric", "id", "id_with_string_value"), config);
+ assertThat(value.asString()).isEmpty();
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/AdapterViewBehavior.java b/robolectric/src/test/java/org/robolectric/shadows/AdapterViewBehavior.java
index 1a8312f0c..a551efa26 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/AdapterViewBehavior.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/AdapterViewBehavior.java
@@ -7,15 +7,15 @@ import android.os.Looper;
import android.view.View;
import android.widget.AdapterView;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
abstract public class AdapterViewBehavior {
private AdapterView adapterView;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ConverterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ConverterTest.java
index e7b20abb5..ea1f7ec44 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ConverterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ConverterTest.java
@@ -2,11 +2,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.res.Fs;
import org.robolectric.res.FsFile;
import org.robolectric.res.Qualifiers;
@@ -14,7 +14,7 @@ import org.robolectric.res.ResType;
import org.robolectric.res.TypedResource;
import org.robolectric.res.XmlContext;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ConverterTest {
private XmlContext xmlContext;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/LegacyManifestParserTest.java b/robolectric/src/test/java/org/robolectric/shadows/LegacyManifestParserTest.java
index 8bb0b3a0e..7307d9b10 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/LegacyManifestParserTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/LegacyManifestParserTest.java
@@ -6,15 +6,15 @@ import static org.robolectric.util.TestUtil.resourceFile;
import android.content.pm.PackageParser.Package;
import android.content.pm.PackageParser.Permission;
import android.content.pm.PermissionInfo;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.manifest.AndroidManifest;
/** Unit test for {@link org.robolectric.shadows.LegacyManifestParser}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class LegacyManifestParserTest {
private AndroidManifest androidManifest;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ResourceHelperTest.java b/robolectric/src/test/java/org/robolectric/shadows/ResourceHelperTest.java
index 32ac135f2..9edaac17a 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ResourceHelperTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ResourceHelperTest.java
@@ -3,15 +3,13 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.util.TypedValue;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-/**
- * Unit tests for {@link ResourceHelper}.
- */
-@RunWith(RobolectricTestRunner.class)
+/** Unit tests for {@link ResourceHelper}. */
+@RunWith(AndroidJUnit4.class)
public class ResourceHelperTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/SQLiteCursorTest.java b/robolectric/src/test/java/org/robolectric/shadows/SQLiteCursorTest.java
index e71dbb945..582e4d744 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/SQLiteCursorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/SQLiteCursorTest.java
@@ -7,13 +7,13 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteCursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
+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;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class SQLiteCursorTest {
private SQLiteDatabase database;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/SQLiteDatabaseTest.java b/robolectric/src/test/java/org/robolectric/shadows/SQLiteDatabaseTest.java
index 1adda38bf..f365dfb53 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/SQLiteDatabaseTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/SQLiteDatabaseTest.java
@@ -6,12 +6,15 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import android.app.Application;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -20,10 +23,8 @@ 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 SQLiteDatabaseTest {
private SQLiteDatabase database;
private List<SQLiteDatabase> openDatabases = new ArrayList<>();
@@ -32,7 +33,8 @@ public class SQLiteDatabaseTest {
@Before
public void setUp() throws Exception {
- databasePath = RuntimeEnvironment.application.getDatabasePath("database.db");
+ databasePath =
+ ((Application) ApplicationProvider.getApplicationContext()).getDatabasePath("database.db");
databasePath.getParentFile().mkdirs();
database = openOrCreateDatabase(databasePath);
@@ -921,7 +923,8 @@ public class SQLiteDatabaseTest {
/////////////////////
private SQLiteDatabase openOrCreateDatabase(String name) {
- return openOrCreateDatabase(RuntimeEnvironment.application.getDatabasePath(name));
+ return openOrCreateDatabase(
+ ((Application) ApplicationProvider.getApplicationContext()).getDatabasePath(name));
}
private SQLiteDatabase openOrCreateDatabase(File databasePath) {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/SQLiteOpenHelperTest.java b/robolectric/src/test/java/org/robolectric/shadows/SQLiteOpenHelperTest.java
index 478a2ec27..11454b55e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/SQLiteOpenHelperTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/SQLiteOpenHelperTest.java
@@ -2,26 +2,29 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
+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 SQLiteOpenHelperTest {
private TestOpenHelper helper;
@Before
public void setUp() throws Exception {
- helper = new TestOpenHelper(RuntimeEnvironment.application, "path", null, 1);
+ helper =
+ new TestOpenHelper(
+ (Application) ApplicationProvider.getApplicationContext(), "path", null, 1);
}
@After
@@ -95,18 +98,30 @@ public class SQLiteOpenHelperTest {
public void testGetPath() throws Exception {
final String path1 = "path1", path2 = "path2";
- TestOpenHelper helper1 = new TestOpenHelper(RuntimeEnvironment.application, path1, null, 1);
- String expectedPath1 = RuntimeEnvironment.application.getDatabasePath(path1).getAbsolutePath();
+ TestOpenHelper helper1 =
+ new TestOpenHelper(
+ (Application) ApplicationProvider.getApplicationContext(), path1, null, 1);
+ String expectedPath1 =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getDatabasePath(path1)
+ .getAbsolutePath();
assertThat(helper1.getReadableDatabase().getPath()).isEqualTo(expectedPath1);
- TestOpenHelper helper2 = new TestOpenHelper(RuntimeEnvironment.application, path2, null, 1);
- String expectedPath2 = RuntimeEnvironment.application.getDatabasePath(path2).getAbsolutePath();
+ TestOpenHelper helper2 =
+ new TestOpenHelper(
+ (Application) ApplicationProvider.getApplicationContext(), path2, null, 1);
+ String expectedPath2 =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getDatabasePath(path2)
+ .getAbsolutePath();
assertThat(helper2.getReadableDatabase().getPath()).isEqualTo(expectedPath2);
}
@Test
public void testCloseMultipleDbs() throws Exception {
- TestOpenHelper helper2 = new TestOpenHelper(RuntimeEnvironment.application, "path2", null, 1);
+ TestOpenHelper helper2 =
+ new TestOpenHelper(
+ (Application) ApplicationProvider.getApplicationContext(), "path2", null, 1);
SQLiteDatabase database1 = helper.getWritableDatabase();
SQLiteDatabase database2 = helper2.getWritableDatabase();
assertThat(database1.isOpen()).isTrue();
@@ -120,7 +135,9 @@ public class SQLiteOpenHelperTest {
@Test
public void testOpenMultipleDbsOnCreate() throws Exception {
- TestOpenHelper helper2 = new TestOpenHelper(RuntimeEnvironment.application, "path2", null, 1);
+ TestOpenHelper helper2 =
+ new TestOpenHelper(
+ (Application) ApplicationProvider.getApplicationContext(), "path2", null, 1);
assertThat(helper.onCreateCalled).isFalse();
assertThat(helper2.onCreateCalled).isFalse();
helper.getWritableDatabase();
@@ -149,7 +166,7 @@ public class SQLiteOpenHelperTest {
private void verifyData(SQLiteDatabase db, String table, int expectedVals) {
assertThat(db.query(table, null, null, null,
- null, null, null).getCount()).isEqualTo(expectedVals);
+ null, null, null).getCount()).isEqualTo(expectedVals);
}
@Test
@@ -158,7 +175,9 @@ public class SQLiteOpenHelperTest {
SQLiteDatabase db1 = helper.getWritableDatabase();
setupTable(db1, TABLE_NAME1);
insertData(db1, TABLE_NAME1, new int[]{1, 2});
- TestOpenHelper helper2 = new TestOpenHelper(RuntimeEnvironment.application, "path2", null, 1);
+ TestOpenHelper helper2 =
+ new TestOpenHelper(
+ (Application) ApplicationProvider.getApplicationContext(), "path2", null, 1);
SQLiteDatabase db2 = helper2.getWritableDatabase();
setupTable(db2, TABLE_NAME2);
insertData(db2, TABLE_NAME2, new int[]{4, 5, 6});
@@ -169,7 +188,9 @@ public class SQLiteOpenHelperTest {
@Test
public void testCloseOneDbKeepsDataForOther() throws Exception {
final String TABLE_NAME1 = "fart", TABLE_NAME2 = "fart2";
- TestOpenHelper helper2 = new TestOpenHelper(RuntimeEnvironment.application, "path2", null, 1);
+ TestOpenHelper helper2 =
+ new TestOpenHelper(
+ (Application) ApplicationProvider.getApplicationContext(), "path2", null, 1);
SQLiteDatabase db1 = helper.getWritableDatabase();
SQLiteDatabase db2 = helper2.getWritableDatabase();
setupTable(db1, TABLE_NAME1);
@@ -231,9 +252,9 @@ public class SQLiteOpenHelperTest {
}
@Override
- public void onCreate(SQLiteDatabase database) {
- onCreateCalled = true;
- }
+ public void onCreate(SQLiteDatabase database) {
+ onCreateCalled = true;
+ }
@Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/SQLiteQueryBuilderTest.java b/robolectric/src/test/java/org/robolectric/shadows/SQLiteQueryBuilderTest.java
index 972a33754..fbc14077c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/SQLiteQueryBuilderTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/SQLiteQueryBuilderTest.java
@@ -6,13 +6,13 @@ import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
+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;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class SQLiteQueryBuilderTest {
private static final String TABLE_NAME = "sqlBuilderTest";
diff --git a/robolectric/src/test/java/org/robolectric/shadows/SQLiteStatementTest.java b/robolectric/src/test/java/org/robolectric/shadows/SQLiteStatementTest.java
index 50f4511f7..220ab0c0f 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/SQLiteStatementTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/SQLiteStatementTest.java
@@ -3,25 +3,27 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
+import android.app.Application;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDoneException;
import android.database.sqlite.SQLiteStatement;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
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 SQLiteStatementTest {
private SQLiteDatabase database;
@Before
public void setUp() throws Exception {
- final File databasePath = RuntimeEnvironment.application.getDatabasePath("path");
+ final File databasePath =
+ ((Application) ApplicationProvider.getApplicationContext()).getDatabasePath("path");
databasePath.getParentFile().mkdirs();
database = SQLiteDatabase.openOrCreateDatabase(databasePath.getPath(), null);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSeekBarTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSeekBarTest.java
index ef3e3e3a3..caecc3330 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSeekBarTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSeekBarTest.java
@@ -2,21 +2,23 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.content.Context;
import android.widget.AbsSeekBar;
+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;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAbsSeekBarTest {
@Test
public void testInheritance() {
// TODO: this seems to test static typing - compiler enforces this ;)
- TestAbsSeekBar seekBar = new TestAbsSeekBar(RuntimeEnvironment.application);
+ TestAbsSeekBar seekBar =
+ new TestAbsSeekBar((Application) ApplicationProvider.getApplicationContext());
ShadowAbsSeekBar shadow = Shadows.shadowOf(seekBar);
assertThat(shadow).isInstanceOf(ShadowProgressBar.class);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSpinnerAdapterViewBehaviorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSpinnerAdapterViewBehaviorTest.java
index 90c325eb0..880a7ec17 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSpinnerAdapterViewBehaviorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSpinnerAdapterViewBehaviorTest.java
@@ -1,14 +1,15 @@
package org.robolectric.shadows;
+import android.app.Application;
import android.widget.AdapterView;
import android.widget.Gallery;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAbsSpinnerAdapterViewBehaviorTest extends AdapterViewBehavior {
@Override public AdapterView createAdapterView() {
- return new Gallery(RuntimeEnvironment.application);
+ return new Gallery((Application) ApplicationProvider.getApplicationContext());
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSpinnerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSpinnerTest.java
index 8609449e5..c4e8e3f63 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSpinnerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsSpinnerTest.java
@@ -3,18 +3,19 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
+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 ShadowAbsSpinnerTest {
private Context context;
private Spinner spinner;
@@ -23,7 +24,7 @@ public class ShadowAbsSpinnerTest {
@Before
public void setUp() throws Exception {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
spinner = new Spinner(context);
shadowSpinner = shadowOf(spinner);
String [] testItems = {"foo", "bar"};
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsoluteLayoutTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsoluteLayoutTest.java
index d154a9aba..96aef3b0d 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsoluteLayoutTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAbsoluteLayoutTest.java
@@ -2,22 +2,26 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.view.ViewGroup;
import android.widget.AbsoluteLayout;
+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 ShadowAbsoluteLayoutTest {
@Test
public void getLayoutParams_shouldReturnAbsoluteLayoutParams() throws Exception {
- ViewGroup.LayoutParams layoutParams = (new AbsoluteLayout(RuntimeEnvironment.application) {
- @Override protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
- return super.generateDefaultLayoutParams();
- }
- }).generateDefaultLayoutParams();
+ ViewGroup.LayoutParams layoutParams =
+ (new AbsoluteLayout((Application) ApplicationProvider.getApplicationContext()) {
+ @Override
+ protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
+ return super.generateDefaultLayoutParams();
+ }
+ })
+ .generateDefaultLayoutParams();
assertThat(layoutParams).isInstanceOf(AbsoluteLayout.LayoutParams.class);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAbstractCursorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAbstractCursorTest.java
index 00ac8855c..009a70482 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAbstractCursorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAbstractCursorTest.java
@@ -2,18 +2,19 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.database.AbstractCursor;
import android.net.Uri;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAbstractCursorTest {
private TestCursor cursor;
@@ -208,7 +209,8 @@ public class ShadowAbstractCursorTest {
Uri uri = Uri.parse("content://foo.com");
ShadowAbstractCursor shadow = Shadows.shadowOf(cursor);
assertThat(shadow.getNotificationUri_Compatibility()).isNull();
- cursor.setNotificationUri(RuntimeEnvironment.application.getContentResolver(), uri);
+ cursor.setNotificationUri(
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver(), uri);
assertThat(shadow.getNotificationUri_Compatibility()).isEqualTo(uri);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityEventTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityEventTest.java
index b9e689375..202480a5c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityEventTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityEventTest.java
@@ -3,19 +3,20 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.Notification;
import android.os.Parcel;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.TextView;
+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 ShadowAccessibilityEventTest {
private AccessibilityEvent event;
@@ -68,7 +69,7 @@ public class ShadowAccessibilityEventTest {
@Test
public void shouldHaveCurrentSourceId() {
- TextView rootView = new TextView(RuntimeEnvironment.application);
+ TextView rootView = new TextView((Application) ApplicationProvider.getApplicationContext());
event.setSource(rootView);
assertThat(shadowOf(event).getSourceRoot()).isEqualTo(rootView);
assertThat(shadowOf(event).getVirtualDescendantId())
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityManagerTest.java
index 43fdca591..93e9f2bd4 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityManagerTest.java
@@ -6,28 +6,32 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.Application;
import android.content.Context;
import android.content.pm.ServiceInfo;
import android.view.accessibility.AccessibilityManager;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAccessibilityManagerTest {
private AccessibilityManager accessibilityManager;
@Before
public void setUp() throws Exception {
- accessibilityManager = (AccessibilityManager) RuntimeEnvironment.application.getSystemService(ACCESSIBILITY_SERVICE);
+ accessibilityManager =
+ (AccessibilityManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(ACCESSIBILITY_SERVICE);
}
@Test
@@ -40,8 +44,11 @@ public class ShadowAccessibilityManagerTest {
// Emulates Android framework behavior, e.g.,
// AccessibilityManager.getInstance(context).isEnabled().
private static AccessibilityManager getAccessibilityManagerInstance() throws Exception {
- return ReflectionHelpers.callStaticMethod(AccessibilityManager.class, "getInstance",
- ReflectionHelpers.ClassParameter.from(Context.class, RuntimeEnvironment.application));
+ return ReflectionHelpers.callStaticMethod(
+ AccessibilityManager.class,
+ "getInstance",
+ ReflectionHelpers.ClassParameter.from(
+ Context.class, (Application) ApplicationProvider.getApplicationContext()));
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityNodeInfoTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityNodeInfoTest.java
index 12a7b1e00..d4c1f68ec 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityNodeInfoTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityNodeInfoTest.java
@@ -4,6 +4,7 @@ import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Parcel;
@@ -11,15 +12,15 @@ import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.accessibility.AccessibilityWindowInfo;
+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;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAccessibilityNodeInfoTest {
private AccessibilityNodeInfo node;
@@ -169,7 +170,7 @@ public class ShadowAccessibilityNodeInfoTest {
@Test
public void equalsTest_nodesFromTheSameViewAreEqual() {
- View view = new View(RuntimeEnvironment.application);
+ View view = new View((Application) ApplicationProvider.getApplicationContext());
AccessibilityNodeInfo nodeA = AccessibilityNodeInfo.obtain(view);
AccessibilityNodeInfo nodeB = AccessibilityNodeInfo.obtain(view);
shadowOf(nodeA).setText("tomato");
@@ -180,8 +181,8 @@ public class ShadowAccessibilityNodeInfoTest {
@Test
public void equalsTest_nodesFromDifferentViewsAreNotEqual() {
- View viewA = new View(RuntimeEnvironment.application);
- View viewB = new View(RuntimeEnvironment.application);
+ View viewA = new View((Application) ApplicationProvider.getApplicationContext());
+ View viewB = new View((Application) ApplicationProvider.getApplicationContext());
AccessibilityNodeInfo nodeA = AccessibilityNodeInfo.obtain(viewA);
AccessibilityNodeInfo nodeB = AccessibilityNodeInfo.obtain(viewB);
shadowOf(nodeA).setText("test");
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityServiceTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityServiceTest.java
index 030b8fbe6..e3a954721 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityServiceTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityServiceTest.java
@@ -5,13 +5,13 @@ import static org.robolectric.Shadows.shadowOf;
import android.accessibilityservice.AccessibilityService;
import android.view.accessibility.AccessibilityEvent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAccessibilityServiceTest {
private MyService service ;
private ShadowAccessibilityService shadow;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityWindowInfoTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityWindowInfoTest.java
index c8e21f45b..36af4e1d5 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityWindowInfoTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccessibilityWindowInfoTest.java
@@ -6,13 +6,13 @@ import static org.robolectric.Shadows.shadowOf;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
+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.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowAccessibilityWindowInfoTest {
private AccessibilityWindowInfo window;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccountManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccountManagerTest.java
index f84383a9a..6b2655b58 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccountManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccountManagerTest.java
@@ -16,21 +16,22 @@ import android.accounts.AuthenticatorException;
import android.accounts.OnAccountsUpdateListener;
import android.accounts.OperationCanceledException;
import android.app.Activity;
+import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.Scheduler;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAccountManagerTest {
private AccountManager am;
private Scheduler scheduler;
@@ -38,7 +39,7 @@ public class ShadowAccountManagerTest {
@Before
public void setUp() throws Exception {
- am = AccountManager.get(RuntimeEnvironment.application);
+ am = AccountManager.get((Application) ApplicationProvider.getApplicationContext());
scheduler = Robolectric.getForegroundThreadScheduler();
activity = new Activity();
}
@@ -46,9 +47,11 @@ public class ShadowAccountManagerTest {
@Test
public void testGet() {
assertThat(am).isNotNull();
- assertThat(am).isSameAs(AccountManager.get(RuntimeEnvironment.application));
+ assertThat(am)
+ .isSameAs(AccountManager.get((Application) ApplicationProvider.getApplicationContext()));
- AccountManager activityAM = AccountManager.get(RuntimeEnvironment.application);
+ AccountManager activityAM =
+ AccountManager.get((Application) ApplicationProvider.getApplicationContext());
assertThat(activityAM).isNotNull();
assertThat(activityAM).isSameAs(am);
}
@@ -642,7 +645,10 @@ public class ShadowAccountManagerTest {
@Test
public void testGetAsSystemService() throws Exception {
- AccountManager systemService = (AccountManager) RuntimeEnvironment.application.getSystemService(Context.ACCOUNT_SERVICE);
+ AccountManager systemService =
+ (AccountManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.ACCOUNT_SERVICE);
assertThat(systemService).isNotNull();
assertThat(am).isEqualTo(systemService);
}
@@ -672,6 +678,31 @@ public class ShadowAccountManagerTest {
}
@Test
+ public void getAuthToken_withActivity_returnsAuthIntent() throws Exception {
+ Account account = new Account("name", "google.com");
+ shadowOf(am).addAccount(account);
+ shadowOf(am).addAuthenticator("google.com");
+
+ TestAccountManagerCallback<Bundle> callback = new TestAccountManagerCallback<>();
+ AccountManagerFuture<Bundle> future = am.getAuthToken(account,
+ "auth_token_type",
+ new Bundle(),
+ activity,
+ callback,
+ new Handler());
+
+ assertThat(future.isDone()).isTrue();
+ assertThat(future.getResult().getString(AccountManager.KEY_ACCOUNT_NAME))
+ .isEqualTo(account.name);
+ assertThat(future.getResult().getString(AccountManager.KEY_ACCOUNT_TYPE))
+ .isEqualTo(account.type);
+ assertThat(future.getResult().getString(AccountManager.KEY_AUTHTOKEN)).isNull();
+ assertThat((Intent) future.getResult().getParcelable(AccountManager.KEY_INTENT)).isNotNull();
+
+ assertThat(callback.hasBeenCalled()).isTrue();
+ }
+
+ @Test
public void getAuthToken_withNotifyAuthFailureSetToFalse_returnsCorrectToken() throws Exception {
Account account = new Account("name", "google.com");
shadowOf(am).addAccount(account);
@@ -700,6 +731,33 @@ public class ShadowAccountManagerTest {
}
@Test
+ public void getAuthToken_withNotifyAuthFailureSetToFalse_returnsAuthIntent() throws Exception {
+ Account account = new Account("name", "google.com");
+ shadowOf(am).addAccount(account);
+ shadowOf(am).addAuthenticator("google.com");
+
+ TestAccountManagerCallback<Bundle> callback = new TestAccountManagerCallback<>();
+ AccountManagerFuture<Bundle> future =
+ am.getAuthToken(
+ account,
+ "auth_token_type",
+ new Bundle(),
+ /* notifyAuthFailure= */ false,
+ callback,
+ new Handler());
+
+ assertThat(future.isDone()).isTrue();
+ assertThat(future.getResult().getString(AccountManager.KEY_ACCOUNT_NAME))
+ .isEqualTo(account.name);
+ assertThat(future.getResult().getString(AccountManager.KEY_ACCOUNT_TYPE))
+ .isEqualTo(account.type);
+ assertThat(future.getResult().getString(AccountManager.KEY_AUTHTOKEN)).isNull();
+ assertThat((Intent) future.getResult().getParcelable(AccountManager.KEY_INTENT)).isNotNull();
+
+ assertThat(callback.hasBeenCalled()).isTrue();
+ }
+
+ @Test
public void getHasFeatures_returnsTrueWhenAllFeaturesSatisfied() throws Exception {
Account account = new Account("name", "google.com");
shadowOf(am).addAccount(account);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccountTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccountTest.java
index 5e9ae3d22..2f509f367 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAccountTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAccountTest.java
@@ -4,11 +4,11 @@ import static com.google.common.truth.Truth.assertThat;
import android.accounts.Account;
import android.os.Parcel;
+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 ShadowAccountTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowActivityGroupTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowActivityGroupTest.java
index 3513a0ed8..5a649e928 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowActivityGroupTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowActivityGroupTest.java
@@ -5,11 +5,11 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
import android.app.ActivityGroup;
+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 ShadowActivityGroupTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowActivityManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowActivityManagerTest.java
index 7e1ed6c4c..9502b2f7e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowActivityManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowActivityManagerTest.java
@@ -8,18 +8,19 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.ActivityManager;
import android.app.ActivityManager.AppTask;
+import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.os.Process;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.collect.Lists;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowActivityManagerTest {
@Test
@@ -81,7 +82,11 @@ public class ShadowActivityManagerTest {
ActivityManager.RunningAppProcessInfo myInfo = activityManager.getRunningAppProcesses().get(0);
assertThat(myInfo.pid).isEqualTo(android.os.Process.myPid());
assertThat(myInfo.uid).isEqualTo(android.os.Process.myUid());
- assertThat(myInfo.processName).isEqualTo(RuntimeEnvironment.application.getBaseContext().getPackageName());
+ assertThat(myInfo.processName)
+ .isEqualTo(
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getBaseContext()
+ .getPackageName());
shadowOf(activityManager).setProcesses(Lists.newArrayList(process1, process2));
assertThat(activityManager.getRunningAppProcesses()).containsExactly(process1, process2);
}
@@ -165,8 +170,9 @@ public class ShadowActivityManagerTest {
///////////////////////
private ActivityManager getActivityManager() {
- return (ActivityManager) RuntimeEnvironment.application.getSystemService(
- Context.ACTIVITY_SERVICE);
+ return (ActivityManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.ACTIVITY_SERVICE);
}
private ActivityManager.RunningTaskInfo buildTaskInfo(ComponentName name) {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowActivityTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowActivityTest.java
index 714b93304..baee15d35 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowActivityTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowActivityTest.java
@@ -48,6 +48,8 @@ import android.view.Window;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.SearchView;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -55,14 +57,12 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.util.TestRunnable;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowActivityTest {
private Activity activity;
@@ -295,7 +295,8 @@ public class ShadowActivityTest {
@Test
public void shouldRetrievePackageNameFromTheManifest() throws Exception {
- assertThat(Robolectric.setupActivity(Activity.class).getPackageName()).isEqualTo(RuntimeEnvironment.application.getPackageName());
+ assertThat(Robolectric.setupActivity(Activity.class).getPackageName())
+ .isEqualTo(((Application) ApplicationProvider.getApplicationContext()).getPackageName());
}
@Test
@@ -843,7 +844,8 @@ public class ShadowActivityTest {
public void shouldCallActivityLifecycleCallbacks() {
final List<String> transcript = new ArrayList<>();
final ActivityController<Activity> controller = buildActivity(Activity.class);
- RuntimeEnvironment.application.registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks(transcript));
+ ((Application) ApplicationProvider.getApplicationContext())
+ .registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks(transcript));
controller.create();
assertThat(transcript).containsExactly("onActivityCreated");
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAlarmManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAlarmManagerTest.java
index dd1778fbb..0acaf7816 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAlarmManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAlarmManagerTest.java
@@ -14,22 +14,23 @@ import android.app.Activity;
import android.app.AlarmManager;
import android.app.AlarmManager.AlarmClockInfo;
import android.app.AlarmManager.OnAlarmListener;
+import android.app.Application;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build.VERSION_CODES;
import android.os.Handler;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Date;
import java.util.TimeZone;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAlarmManagerTest {
private Context context;
@@ -39,7 +40,7 @@ public class ShadowAlarmManagerTest {
@Before
public void setUp() {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
shadowAlarmManager = shadowOf(alarmManager);
activity = Robolectric.setupActivity(Activity.class);
@@ -286,12 +287,18 @@ public class ShadowAlarmManagerTest {
@Test
public void schedule_useRequestCodeToMatchExistingPendingIntents() throws Exception {
Intent intent = new Intent("ACTION!");
- PendingIntent pI = PendingIntent.getService(RuntimeEnvironment.application, 1, intent, 0);
+ PendingIntent pI =
+ PendingIntent.getService(
+ (Application) ApplicationProvider.getApplicationContext(), 1, intent, 0);
AlarmManager alarmManager =
- (AlarmManager) RuntimeEnvironment.application.getSystemService(Context.ALARM_SERVICE);
+ (AlarmManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 10, pI);
- PendingIntent pI2 = PendingIntent.getService(RuntimeEnvironment.application, 2, intent, 0);
+ PendingIntent pI2 =
+ PendingIntent.getService(
+ (Application) ApplicationProvider.getApplicationContext(), 2, intent, 0);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 10, pI2);
assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(2);
@@ -300,12 +307,18 @@ public class ShadowAlarmManagerTest {
@Test
public void cancel_useRequestCodeToMatchExistingPendingIntents() throws Exception {
Intent intent = new Intent("ACTION!");
- PendingIntent pI = PendingIntent.getService(RuntimeEnvironment.application, 1, intent, 0);
+ PendingIntent pI =
+ PendingIntent.getService(
+ (Application) ApplicationProvider.getApplicationContext(), 1, intent, 0);
AlarmManager alarmManager =
- (AlarmManager) RuntimeEnvironment.application.getSystemService(Context.ALARM_SERVICE);
+ (AlarmManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 10, pI);
- PendingIntent pI2 = PendingIntent.getService(RuntimeEnvironment.application, 2, intent, 0);
+ PendingIntent pI2 =
+ PendingIntent.getService(
+ (Application) ApplicationProvider.getApplicationContext(), 2, intent, 0);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 10, pI2);
assertThat(shadowAlarmManager.getScheduledAlarms()).hasSize(2);
@@ -319,7 +332,9 @@ public class ShadowAlarmManagerTest {
@Config(minSdk = N)
public void cancel_removesMatchingListeners() {
Intent intent = new Intent("ACTION!");
- PendingIntent pI = PendingIntent.getService(RuntimeEnvironment.application, 1, intent, 0);
+ PendingIntent pI =
+ PendingIntent.getService(
+ (Application) ApplicationProvider.getApplicationContext(), 1, intent, 0);
OnAlarmListener listener1 = () -> {};
OnAlarmListener listener2 = () -> {};
Handler handler = new Handler();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAlertDialogTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAlertDialogTest.java
index 7c7f37d51..8fdb30a9d 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAlertDialogTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAlertDialogTest.java
@@ -12,24 +12,25 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
import android.app.AlertDialog;
+import android.app.Application;
import android.app.Dialog;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.CustomView;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAlertDialogTest {
@Test
@@ -187,7 +188,9 @@ public class ShadowAlertDialogTest {
@Test
public void testBuilderWithItemArrayViaResourceId() throws Exception {
- AlertDialog.Builder builder = new AlertDialog.Builder(new ContextWrapper(RuntimeEnvironment.application));
+ AlertDialog.Builder builder =
+ new AlertDialog.Builder(
+ new ContextWrapper((Application) ApplicationProvider.getApplicationContext()));
builder.setTitle("title");
builder.setItems(R.array.alertDialogTestItems, new TestDialogOnClickListener());
@@ -210,7 +213,12 @@ public class ShadowAlertDialogTest {
list.add(99);
list.add(88);
list.add(77);
- ArrayAdapter<Integer> adapter = new ArrayAdapter<>(RuntimeEnvironment.application, R.layout.main, R.id.title, list);
+ ArrayAdapter<Integer> adapter =
+ new ArrayAdapter<>(
+ (Application) ApplicationProvider.getApplicationContext(),
+ R.layout.main,
+ R.id.title,
+ list);
AlertDialog.Builder builder = new AlertDialog.Builder(application);
builder.setSingleChoiceItems(adapter, -1, new DialogInterface.OnClickListener() {
@@ -230,7 +238,8 @@ public class ShadowAlertDialogTest {
@Test
public void show_setsLatestAlertDialogAndLatestDialog() {
- AlertDialog alertDialog = new AlertDialog.Builder(RuntimeEnvironment.application).create();
+ AlertDialog alertDialog =
+ new AlertDialog.Builder((Application) ApplicationProvider.getApplicationContext()).create();
assertNull(ShadowDialog.getLatestDialog());
assertNull(ShadowAlertDialog.getLatestAlertDialog());
@@ -242,14 +251,21 @@ public class ShadowAlertDialogTest {
@Test
public void shouldCallTheClickListenerOfTheCheckedAdapterInASingleChoiceDialog() throws Exception {
- AlertDialog.Builder builder = new AlertDialog.Builder(new ContextWrapper(RuntimeEnvironment.application));
+ AlertDialog.Builder builder =
+ new AlertDialog.Builder(
+ new ContextWrapper((Application) ApplicationProvider.getApplicationContext()));
TestDialogOnClickListener listener = new TestDialogOnClickListener();
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
- ArrayAdapter<Integer> arrayAdapter = new ArrayAdapter<>(RuntimeEnvironment.application, R.layout.main, R.id.title, list);
+ ArrayAdapter<Integer> arrayAdapter =
+ new ArrayAdapter<>(
+ (Application) ApplicationProvider.getApplicationContext(),
+ R.layout.main,
+ R.id.title,
+ list);
builder.setSingleChoiceItems(arrayAdapter, 1, listener);
AlertDialog alert = builder.create();
@@ -267,8 +283,8 @@ public class ShadowAlertDialogTest {
@Test
public void shouldDelegateToDialogFindViewByIdIfViewIsNull() {
- AlertDialog dialog = new AlertDialog(RuntimeEnvironment.application) {
- };
+ AlertDialog dialog =
+ new AlertDialog((Application) ApplicationProvider.getApplicationContext()) {};
assertThat((View) dialog.findViewById(99)).isNull();
@@ -307,10 +323,8 @@ public class ShadowAlertDialogTest {
AlertDialog.Builder builder = new AlertDialog.Builder(application);
builder.setIcon(R.drawable.an_image);
- final ShadowAlertDialog alertDialog = shadowOf(builder.create());
- final ShadowAlertController alertController = alertDialog.getShadowAlertController();
-
- assertThat(alertController.getIconId()).isEqualTo(R.drawable.an_image);
+ AlertDialog alertDialog = builder.create();
+ assertThat(shadowOf(alertDialog).getIconId()).isEqualTo(R.drawable.an_image);
}
private static class TestDialogOnClickListener implements DialogInterface.OnClickListener {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAnimationSetTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAnimationSetTest.java
index ebd9f8085..c23a27fb1 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAnimationSetTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAnimationSetTest.java
@@ -7,13 +7,13 @@ import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.TranslateAnimation;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAnimationSetTest {
final Animation.AnimationListener moveListener = mock(Animation.AnimationListener.class);
final Animation.AnimationListener spinListener = mock(Animation.AnimationListener.class);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAnimationUtilsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAnimationUtilsTest.java
index 0a98de0b5..7ecc1f8bf 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAnimationUtilsTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAnimationUtilsTest.java
@@ -6,13 +6,13 @@ import android.R;
import android.app.Activity;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAnimationUtilsTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAppOpsManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAppOpsManagerTest.java
index 440f8af66..61f2288a1 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAppOpsManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAppOpsManagerTest.java
@@ -3,31 +3,42 @@ package org.robolectric.shadows;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_DEFAULT;
import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.AppOpsManager.OPSTR_FINE_LOCATION;
import static android.app.AppOpsManager.OPSTR_GPS;
+import static android.app.AppOpsManager.OP_FINE_LOCATION;
import static android.app.AppOpsManager.OP_GPS;
import static android.app.AppOpsManager.OP_SEND_SMS;
+import static android.app.AppOpsManager.OP_VIBRATE;
import static android.os.Build.VERSION_CODES.KITKAT;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.robolectric.Shadows.shadowOf;
import android.app.AppOpsManager;
+import android.app.AppOpsManager.OnOpChangedListener;
import android.app.AppOpsManager.OpEntry;
import android.app.AppOpsManager.PackageOps;
+import android.app.Application;
import android.content.Context;
+import android.media.AudioAttributes;
+import android.os.Binder;
import android.os.Build.VERSION_CODES;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowAppOpsManager.ModeAndException;
-/**
- * Unit tests for {@link ShadowAppOpsManager}.
- */
-@RunWith(RobolectricTestRunner.class)
+/** Unit tests for {@link ShadowAppOpsManager}. */
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = KITKAT)
public class ShadowAppOpsManagerTest {
@@ -43,8 +54,10 @@ public class ShadowAppOpsManagerTest {
@Before
public void setUp() {
- appOps = (AppOpsManager) RuntimeEnvironment.application.getSystemService(
- Context.APP_OPS_SERVICE);
+ appOps =
+ (AppOpsManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.APP_OPS_SERVICE);
}
@Test
@@ -90,6 +103,40 @@ public class ShadowAppOpsManagerTest {
}
@Test
+ @Config(minSdk = VERSION_CODES.O_MR1)
+ public void noModeSet_atLeastO_noteProxyOpNoThrow_shouldReturnModeAllowed() {
+ assertThat(appOps.noteProxyOpNoThrow(OP_GPS, PACKAGE_NAME1)).isEqualTo(MODE_ALLOWED);
+ }
+
+ @Test
+ @Config(minSdk = VERSION_CODES.O_MR1)
+ public void setMode_withModeDefault_atLeastO_noteProxyOpNoThrow_shouldReturnModeDefault() {
+ appOps.setMode(OP_GPS, Binder.getCallingUid(), PACKAGE_NAME1, MODE_DEFAULT);
+ assertThat(appOps.noteProxyOpNoThrow(OP_GPS, PACKAGE_NAME1)).isEqualTo(MODE_DEFAULT);
+ }
+
+ @Test
+ @Config(minSdk = VERSION_CODES.P)
+ public void setMode_noteProxyOpNoThrow_atLeastO() {
+ assertThat(appOps.noteProxyOpNoThrow(OP_GPS, PACKAGE_NAME1)).isEqualTo(MODE_ALLOWED);
+ appOps.setMode(OP_GPS, Binder.getCallingUid(), PACKAGE_NAME1, MODE_ERRORED);
+ assertThat(appOps.noteProxyOpNoThrow(OP_GPS, PACKAGE_NAME1)).isEqualTo(MODE_ERRORED);
+ }
+
+ @Test
+ @Config(minSdk = VERSION_CODES.KITKAT)
+ public void startStopWatchingMode() {
+ OnOpChangedListener callback = mock(OnOpChangedListener.class);
+ appOps.startWatchingMode(OPSTR_FINE_LOCATION, PACKAGE_NAME1, callback);
+ appOps.setMode(OP_FINE_LOCATION, UID_1, PACKAGE_NAME1, MODE_ERRORED);
+ verify(callback).onOpChanged(OPSTR_FINE_LOCATION, PACKAGE_NAME1);
+
+ appOps.stopWatchingMode(callback);
+ appOps.setMode(OP_FINE_LOCATION, UID_1, PACKAGE_NAME1, MODE_ALLOWED);
+ verifyNoMoreInteractions(callback);
+ }
+
+ @Test
public void noteOp() {
assertThat(appOps.noteOp(OP_GPS, UID_1, PACKAGE_NAME1)).isEqualTo(MODE_ALLOWED);
// Use same op more than once
@@ -120,22 +167,61 @@ public class ShadowAppOpsManagerTest {
@Test
public void getOpsForPackage_withOpFilter() {
- List<PackageOps> results = appOps.getOpsForPackage(
- UID_1, PACKAGE_NAME1, new int[]{OP_GPS});
+ List<PackageOps> results = appOps.getOpsForPackage(UID_1, PACKAGE_NAME1, new int[] {OP_GPS});
assertOps(results);
appOps.noteOp(OP_SEND_SMS, UID_1, PACKAGE_NAME1);
- results = appOps.getOpsForPackage(UID_1, PACKAGE_NAME1, new int[]{OP_GPS});
+ results = appOps.getOpsForPackage(UID_1, PACKAGE_NAME1, new int[] {OP_GPS});
assertOps(results);
appOps.noteOp(OP_GPS, UID_1, PACKAGE_NAME1);
- results = appOps.getOpsForPackage(UID_1, PACKAGE_NAME1, new int[]{OP_GPS});
+ results = appOps.getOpsForPackage(UID_1, PACKAGE_NAME1, new int[] {OP_GPS});
assertOps(results, OP_GPS);
}
- /**
- * Assert that the results contain the expected op codes.
- */
+ @Test
+ @Config(minSdk = VERSION_CODES.LOLLIPOP)
+ public void setRestrictions() {
+ appOps.setRestriction(
+ OP_VIBRATE, AudioAttributes.USAGE_NOTIFICATION, MODE_ERRORED, new String[] {PACKAGE_NAME1});
+
+ ModeAndException modeAndException =
+ shadowOf(appOps).getRestriction(OP_VIBRATE, AudioAttributes.USAGE_NOTIFICATION);
+ assertThat(modeAndException.mode).isEqualTo(MODE_ERRORED);
+ assertThat(modeAndException.exceptionPackages).containsExactly(PACKAGE_NAME1);
+ }
+
+ @Test
+ public void checkPackage_doesntExist() {
+ try {
+ appOps.checkPackage(123, PACKAGE_NAME1);
+ fail();
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void checkPackage_doesntBelong() {
+ shadowOf(((Application) ApplicationProvider.getApplicationContext()).getPackageManager())
+ .setPackagesForUid(111, PACKAGE_NAME1);
+ try {
+ appOps.checkPackage(123, PACKAGE_NAME1);
+ fail();
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void checkPackage_belongs() {
+ shadowOf(((Application) ApplicationProvider.getApplicationContext()).getPackageManager())
+ .setPackagesForUid(123, PACKAGE_NAME1);
+ appOps.checkPackage(123, PACKAGE_NAME1);
+ // check passes without exception
+ }
+
+ /** Assert that the results contain the expected op codes. */
private void assertOps(List<PackageOps> pkgOps, Integer... expectedOps) {
Set<Integer> actualOps = new HashSet<>();
for (PackageOps pkgOp : pkgOps) {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAppTaskTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAppTaskTest.java
index 975555e8a..e8fcd4e2f 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAppTaskTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAppTaskTest.java
@@ -8,13 +8,13 @@ import android.app.Activity;
import android.app.ActivityManager.AppTask;
import android.app.ActivityManager.RecentTaskInfo;
import android.content.Intent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowAppTaskTest {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetHostTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetHostTest.java
index 2dbaad948..b5ecc9372 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetHostTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetHostTest.java
@@ -4,17 +4,18 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNotNull;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
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 ShadowAppWidgetHostTest {
private AppWidgetHost appWidgetHost;
private ShadowAppWidgetHost shadowAppWidgetHost;
@@ -22,7 +23,7 @@ public class ShadowAppWidgetHostTest {
@Before
public void setup() throws Exception {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
appWidgetHost = new AppWidgetHost(context, 404);
shadowAppWidgetHost = shadowOf(appWidgetHost);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetHostViewTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetHostViewTest.java
index a89d9a52f..fb6336c75 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetHostViewTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetHostViewTest.java
@@ -3,23 +3,25 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
+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 ShadowAppWidgetHostViewTest {
private AppWidgetHostView appWidgetHostView;
private ShadowAppWidgetHostView shadowAppWidgetHostView;
@Before
public void setUp() throws Exception {
- appWidgetHostView = new AppWidgetHostView(RuntimeEnvironment.application);
+ appWidgetHostView =
+ new AppWidgetHostView((Application) ApplicationProvider.getApplicationContext());
shadowAppWidgetHostView = shadowOf(appWidgetHostView);
}
@@ -43,7 +45,8 @@ public class ShadowAppWidgetHostViewTest {
@Test
public void shouldBeAbleToHaveHostSet() throws Exception {
- AppWidgetHost host = new AppWidgetHost(RuntimeEnvironment.application, 0);
+ AppWidgetHost host =
+ new AppWidgetHost((Application) ApplicationProvider.getApplicationContext(), 0);
shadowAppWidgetHostView.setHost(host);
assertThat(shadowAppWidgetHostView.getHost()).isSameAs(host);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetManagerTest.java
index bfca125b9..f57efb8c8 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAppWidgetManagerTest.java
@@ -8,6 +8,7 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.appwidget.AppWidgetProviderInfo;
@@ -17,30 +18,36 @@ import android.content.ContextWrapper;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.TextView;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAppWidgetManagerTest {
private AppWidgetManager appWidgetManager;
private ShadowAppWidgetManager shadowAppWidgetManager;
@Before
public void setUp() throws Exception {
- appWidgetManager = AppWidgetManager.getInstance(RuntimeEnvironment.application);
+ appWidgetManager =
+ AppWidgetManager.getInstance((Application) ApplicationProvider.getApplicationContext());
shadowAppWidgetManager = shadowOf(appWidgetManager);
}
@Test
public void getInstance_shouldReturnSameInstance() throws Exception {
assertNotNull(appWidgetManager);
- assertSame(AppWidgetManager.getInstance(RuntimeEnvironment.application), appWidgetManager);
- assertSame(AppWidgetManager.getInstance(new ContextWrapper(RuntimeEnvironment.application)), appWidgetManager);
+ assertSame(
+ AppWidgetManager.getInstance((Application) ApplicationProvider.getApplicationContext()),
+ appWidgetManager);
+ assertSame(
+ AppWidgetManager.getInstance(
+ new ContextWrapper((Application) ApplicationProvider.getApplicationContext())),
+ appWidgetManager);
}
@Test
@@ -77,10 +84,18 @@ public class ShadowAppWidgetManagerTest {
View originalWidgetView = shadowAppWidgetManager.getViewFor(widgetId);
assertContains("Main Layout", originalWidgetView);
- appWidgetManager.updateAppWidget(widgetId, new RemoteViews(RuntimeEnvironment.application.getPackageName(), R.layout.main));
+ appWidgetManager.updateAppWidget(
+ widgetId,
+ new RemoteViews(
+ ((Application) ApplicationProvider.getApplicationContext()).getPackageName(),
+ R.layout.main));
assertSame(originalWidgetView, shadowAppWidgetManager.getViewFor(widgetId));
- appWidgetManager.updateAppWidget(widgetId, new RemoteViews(RuntimeEnvironment.application.getPackageName(), R.layout.media));
+ appWidgetManager.updateAppWidget(
+ widgetId,
+ new RemoteViews(
+ ((Application) ApplicationProvider.getApplicationContext()).getPackageName(),
+ R.layout.media));
assertNotSame(originalWidgetView, shadowAppWidgetManager.getViewFor(widgetId));
View mediaWidgetView = shadowAppWidgetManager.getViewFor(widgetId);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowApplicationTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowApplicationTest.java
index 9dc804280..44fe4fb1f 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowApplicationTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowApplicationTest.java
@@ -46,37 +46,34 @@ import android.view.autofill.AutofillManager;
import android.view.textclassifier.TextClassificationManager;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.util.Scheduler;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowApplicationTest {
private Context context;
@Before
public void setUp() {
- context = RuntimeEnvironment.application;
- }
-
- @Test
- @Config(packageName = "override.package")
- public void shouldOverridePackageWithConfig() {
- assertThat(RuntimeEnvironment.application.getPackageName()).isEqualTo("override.package");
+ context = (Application) ApplicationProvider.getApplicationContext();
}
@Test
public void shouldBeAContext() throws Exception {
- assertThat(Robolectric.setupActivity(Activity.class).getApplication()).isSameAs(RuntimeEnvironment.application);
- assertThat(Robolectric.setupActivity(Activity.class).getApplication().getApplicationContext()).isSameAs(RuntimeEnvironment.application);
+ assertThat(Robolectric.setupActivity(Activity.class).getApplication())
+ .isSameAs((Application) ApplicationProvider.getApplicationContext());
+ assertThat(Robolectric.setupActivity(Activity.class).getApplication().getApplicationContext())
+ .isSameAs((Application) ApplicationProvider.getApplicationContext());
}
@Test
@@ -169,9 +166,12 @@ public class ShadowApplicationTest {
@Test
@Config(minSdk = O)
public void shouldProvideServicesIntroducedOreo() throws Exception {
- // Context.AUTOFILL_MANAGER_SERVICE is marked @hide and this is the documented way to obtain this
+ // Context.AUTOFILL_MANAGER_SERVICE is marked @hide and this is the documented way to obtain
+ // this
// service.
- AutofillManager autofillManager = RuntimeEnvironment.application.getSystemService(AutofillManager.class);
+ AutofillManager autofillManager =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(AutofillManager.class);
assertThat(autofillManager).isNotNull();
assertThat(context.getSystemService(Context.TEXT_CLASSIFICATION_SERVICE))
@@ -179,14 +179,19 @@ public class ShadowApplicationTest {
}
@Test public void shouldProvideLayoutInflater() throws Exception {
- Object systemService = RuntimeEnvironment.application.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ Object systemService =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
assertThat(systemService).isInstanceOf(LayoutInflater.class);
}
@Test
@Config(minSdk = KITKAT)
public void shouldCorrectlyInstantiatedAccessibilityService() throws Exception {
- AccessibilityManager accessibilityManager = (AccessibilityManager) RuntimeEnvironment.application.getSystemService(Context.ACCESSIBILITY_SERVICE);
+ AccessibilityManager accessibilityManager =
+ (AccessibilityManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.ACCESSIBILITY_SERVICE);
AccessibilityManager.TouchExplorationStateChangeListener listener = createTouchListener();
assertThat(accessibilityManager.addTouchExplorationStateChangeListener(listener)).isTrue();
@@ -205,19 +210,22 @@ public class ShadowApplicationTest {
TestService service = new TestService();
ComponentName expectedComponentName = new ComponentName("", "");
Binder expectedBinder = new Binder();
- Shadows.shadowOf(RuntimeEnvironment.application).setComponentNameAndServiceForBindService(expectedComponentName, expectedBinder);
- RuntimeEnvironment.application.bindService(new Intent(""), service, Context.BIND_AUTO_CREATE);
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .setComponentNameAndServiceForBindService(expectedComponentName, expectedBinder);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(new Intent(""), service, Context.BIND_AUTO_CREATE);
assertThat(service.name).isEqualTo(expectedComponentName);
assertThat(service.service).isEqualTo(expectedBinder);
assertThat(service.nameUnbound).isNull();
- RuntimeEnvironment.application.unbindService(service);
+ ((Application) ApplicationProvider.getApplicationContext()).unbindService(service);
assertThat(service.nameUnbound).isEqualTo(expectedComponentName);
}
@Test
public void bindServiceShouldCallOnServiceConnectedWithNullValues() {
TestService service = new TestService();
- RuntimeEnvironment.application.bindService(new Intent(""), service, Context.BIND_AUTO_CREATE);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(new Intent(""), service, Context.BIND_AUTO_CREATE);
assertThat(service.name).isNull();
assertThat(service.service).isNull();
}
@@ -228,10 +236,15 @@ public class ShadowApplicationTest {
ComponentName expectedComponentName = new ComponentName("", "");
Binder expectedBinder = new Binder();
Intent expectedIntent = new Intent("expected");
- Shadows.shadowOf(RuntimeEnvironment.application).setComponentNameAndServiceForBindServiceForIntent(expectedIntent, expectedComponentName, expectedBinder);
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .setComponentNameAndServiceForBindServiceForIntent(
+ expectedIntent, expectedComponentName, expectedBinder);
TestService service = new TestService();
- assertThat(RuntimeEnvironment.application.bindService(expectedIntent, service, Context.BIND_AUTO_CREATE)).isTrue();
+ assertThat(
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(expectedIntent, service, Context.BIND_AUTO_CREATE))
+ .isTrue();
assertThat(service.name).isNull();
assertThat(service.service).isNull();
@@ -248,11 +261,14 @@ public class ShadowApplicationTest {
ComponentName expectedComponentName = new ComponentName("", "");
Binder expectedBinder = new Binder();
Intent expectedIntent = new Intent("expected");
- Shadows.shadowOf(RuntimeEnvironment.application).setComponentNameAndServiceForBindServiceForIntent(expectedIntent, expectedComponentName, expectedBinder);
- RuntimeEnvironment.application.bindService(expectedIntent, service, Context.BIND_AUTO_CREATE);
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .setComponentNameAndServiceForBindServiceForIntent(
+ expectedIntent, expectedComponentName, expectedBinder);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(expectedIntent, service, Context.BIND_AUTO_CREATE);
ShadowLooper.pauseMainLooper();
- RuntimeEnvironment.application.unbindService(service);
+ ((Application) ApplicationProvider.getApplicationContext()).unbindService(service);
assertThat(service.nameUnbound).isNull();
ShadowLooper.unPauseMainLooper();
assertThat(service.nameUnbound).isEqualTo(expectedComponentName);
@@ -264,10 +280,12 @@ public class ShadowApplicationTest {
ComponentName expectedComponentName = new ComponentName("", "");
Binder expectedBinder = new Binder();
Intent expectedIntent = new Intent("expected");
- final ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
+ final ShadowApplication shadowApplication =
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext());
shadowApplication.setComponentNameAndServiceForBindServiceForIntent(expectedIntent, expectedComponentName, expectedBinder);
- RuntimeEnvironment.application.bindService(expectedIntent, service, Context.BIND_AUTO_CREATE);
- RuntimeEnvironment.application.unbindService(service);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(expectedIntent, service, Context.BIND_AUTO_CREATE);
+ ((Application) ApplicationProvider.getApplicationContext()).unbindService(service);
assertThat(shadowApplication.getUnboundServiceConnections()).hasSize(1);
assertThat(shadowApplication.getUnboundServiceConnections().get(0)).isSameAs(service);
}
@@ -279,10 +297,13 @@ public class ShadowApplicationTest {
ComponentName expectedComponentName = new ComponentName("", "");
Binder expectedBinder = new Binder();
Intent expectedIntent = new Intent("refuseToBind");
- final ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
+ final ShadowApplication shadowApplication =
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext());
shadowApplication.setComponentNameAndServiceForBindServiceForIntent(expectedIntent, expectedComponentName, expectedBinder);
shadowApplication.declareActionUnbindable(expectedIntent.getAction());
- assertFalse(RuntimeEnvironment.application.bindService(expectedIntent, service, Context.BIND_AUTO_CREATE));
+ assertFalse(
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(expectedIntent, service, Context.BIND_AUTO_CREATE));
ShadowLooper.unPauseMainLooper();
assertThat(service.name).isNull();
assertThat(service.service).isNull();
@@ -298,13 +319,16 @@ public class ShadowApplicationTest {
ComponentName expectedComponentNameTwo = new ComponentName("package", "two");
Binder expectedBinderTwo = new Binder();
Intent expectedIntentTwo = new Intent("expected_two");
- final ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
+ final ShadowApplication shadowApplication =
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext());
shadowApplication.setComponentNameAndServiceForBindServiceForIntent(expectedIntentOne, expectedComponentNameOne, expectedBinderOne);
shadowApplication.setComponentNameAndServiceForBindServiceForIntent(expectedIntentTwo, expectedComponentNameTwo, expectedBinderTwo);
- RuntimeEnvironment.application.bindService(expectedIntentOne, service, Context.BIND_AUTO_CREATE);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(expectedIntentOne, service, Context.BIND_AUTO_CREATE);
assertThat(service.name).isEqualTo(expectedComponentNameOne);
assertThat(service.service).isEqualTo(expectedBinderOne);
- RuntimeEnvironment.application.bindService(expectedIntentTwo, service, Context.BIND_AUTO_CREATE);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(expectedIntentTwo, service, Context.BIND_AUTO_CREATE);
assertThat(service.name).isEqualTo(expectedComponentNameTwo);
assertThat(service.service).isEqualTo(expectedBinderTwo);
}
@@ -318,16 +342,20 @@ public class ShadowApplicationTest {
ComponentName expectedComponentNameTwo = new ComponentName("package", "two");
Binder expectedBinderTwo = new Binder();
Intent expectedIntentTwo = new Intent("expected_two");
- final ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
+ final ShadowApplication shadowApplication =
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext());
shadowApplication.setComponentNameAndServiceForBindServiceForIntent(expectedIntentOne, expectedComponentNameOne, expectedBinderOne);
shadowApplication.setComponentNameAndServiceForBindServiceForIntent(expectedIntentTwo, expectedComponentNameTwo, expectedBinderTwo);
- RuntimeEnvironment.application.bindService(expectedIntentOne, service, Context.BIND_AUTO_CREATE);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(expectedIntentOne, service, Context.BIND_AUTO_CREATE);
assertThat(service.name).isEqualTo(expectedComponentNameOne);
assertThat(service.service).isEqualTo(expectedBinderOne);
- RuntimeEnvironment.application.bindService(expectedIntentTwo, service, Context.BIND_AUTO_CREATE);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(expectedIntentTwo, service, Context.BIND_AUTO_CREATE);
assertThat(service.name).isEqualTo(expectedComponentNameTwo);
assertThat(service.service).isEqualTo(expectedBinderTwo);
- RuntimeEnvironment.application.bindService(new Intent("unknown"), service, Context.BIND_AUTO_CREATE);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(new Intent("unknown"), service, Context.BIND_AUTO_CREATE);
assertThat(service.name).isNull();
assertThat(service.service).isNull();
}
@@ -342,30 +370,35 @@ public class ShadowApplicationTest {
ComponentName expectedComponentNameTwo = new ComponentName("package", "two");
Binder expectedBinderTwo = new Binder();
Intent expectedIntentTwo = new Intent("expected_two");
- final ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
+ final ShadowApplication shadowApplication =
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext());
shadowApplication.setComponentNameAndServiceForBindServiceForIntent(expectedIntentOne, expectedComponentNameOne, expectedBinderOne);
shadowApplication.setComponentNameAndServiceForBindServiceForIntent(expectedIntentTwo, expectedComponentNameTwo, expectedBinderTwo);
- RuntimeEnvironment.application.bindService(expectedIntentOne, serviceOne, Context.BIND_AUTO_CREATE);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(expectedIntentOne, serviceOne, Context.BIND_AUTO_CREATE);
assertThat(serviceOne.nameUnbound).isNull();
- RuntimeEnvironment.application.unbindService(serviceOne);
+ ((Application) ApplicationProvider.getApplicationContext()).unbindService(serviceOne);
assertThat(serviceOne.name).isEqualTo(expectedComponentNameOne);
- RuntimeEnvironment.application.bindService(expectedIntentTwo, serviceTwo, Context.BIND_AUTO_CREATE);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(expectedIntentTwo, serviceTwo, Context.BIND_AUTO_CREATE);
assertThat(serviceTwo.nameUnbound).isNull();
- RuntimeEnvironment.application.unbindService(serviceTwo);
+ ((Application) ApplicationProvider.getApplicationContext()).unbindService(serviceTwo);
assertThat(serviceTwo.name).isEqualTo(expectedComponentNameTwo);
TestService serviceDefault = new TestService();
- RuntimeEnvironment.application.bindService(new Intent("default"), serviceDefault, Context.BIND_AUTO_CREATE);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .bindService(new Intent("default"), serviceDefault, Context.BIND_AUTO_CREATE);
assertThat(serviceDefault.nameUnbound).isNull();
- RuntimeEnvironment.application.unbindService(serviceDefault);
+ ((Application) ApplicationProvider.getApplicationContext()).unbindService(serviceDefault);
assertThat(serviceDefault.name).isNull();
}
@Test
public void shouldHaveStoppedServiceIntentAndIndicateServiceWasntRunning() {
- ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
+ ShadowApplication shadowApplication =
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext());
Activity activity = Robolectric.setupActivity(Activity.class);
@@ -385,7 +418,8 @@ public class ShadowApplicationTest {
@Test
public void shouldHaveStoppedServiceIntentAndIndicateServiceWasRunning() {
- ShadowApplication shadowApplication = shadowOf(RuntimeEnvironment.application);
+ ShadowApplication shadowApplication =
+ shadowOf((Application) ApplicationProvider.getApplicationContext());
Activity activity = Robolectric.setupActivity(Activity.class);
@@ -401,7 +435,8 @@ public class ShadowApplicationTest {
@Test
public void shouldHaveStoppedServiceByStartedComponent() {
- ShadowApplication shadowApplication = shadowOf(RuntimeEnvironment.application);
+ ShadowApplication shadowApplication =
+ shadowOf((Application) ApplicationProvider.getApplicationContext());
Activity activity = Robolectric.setupActivity(Activity.class);
@@ -424,7 +459,7 @@ public class ShadowApplicationTest {
@Test
public void shouldClearStartedServiceIntents() {
- Application application = RuntimeEnvironment.application;
+ Application application = (Application) ApplicationProvider.getApplicationContext();
application.startService(getSomeActionIntent("some.action"));
application.startService(getSomeActionIntent("another.action"));
@@ -439,7 +474,8 @@ public class ShadowApplicationTest {
activity.registerReceiver(new TestBroadcastReceiver(), new IntentFilter("Foo"));
try {
- shadowOf(RuntimeEnvironment.application).assertNoBroadcastListenersOfActionRegistered(activity, "Foo");
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .assertNoBroadcastListenersOfActionRegistered(activity, "Foo");
fail("should have thrown IllegalStateException");
} catch (IllegalStateException e) {
@@ -452,15 +488,18 @@ public class ShadowApplicationTest {
Activity activity = Robolectric.setupActivity(Activity.class);
activity.registerReceiver(new TestBroadcastReceiver(), new IntentFilter("Foo"));
- shadowOf(RuntimeEnvironment.application).assertNoBroadcastListenersOfActionRegistered(activity, "Bar");
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .assertNoBroadcastListenersOfActionRegistered(activity, "Bar");
}
@Test
public void canAnswerIfReceiverIsRegisteredForIntent() throws Exception {
BroadcastReceiver expectedReceiver = new TestBroadcastReceiver();
- ShadowApplication shadowApplication = shadowOf(RuntimeEnvironment.application);
+ ShadowApplication shadowApplication =
+ shadowOf((Application) ApplicationProvider.getApplicationContext());
assertFalse(shadowApplication.hasReceiverForIntent(new Intent("Foo")));
- RuntimeEnvironment.application.registerReceiver(expectedReceiver, new IntentFilter("Foo"));
+ ((Application) ApplicationProvider.getApplicationContext())
+ .registerReceiver(expectedReceiver, new IntentFilter("Foo"));
assertTrue(shadowApplication.hasReceiverForIntent(new Intent("Foo")));
}
@@ -468,10 +507,13 @@ public class ShadowApplicationTest {
@Test
public void canFindAllReceiversForAnIntent() throws Exception {
BroadcastReceiver expectedReceiver = new TestBroadcastReceiver();
- ShadowApplication shadowApplication = shadowOf(RuntimeEnvironment.application);
+ ShadowApplication shadowApplication =
+ shadowOf((Application) ApplicationProvider.getApplicationContext());
assertFalse(shadowApplication.hasReceiverForIntent(new Intent("Foo")));
- RuntimeEnvironment.application.registerReceiver(expectedReceiver, new IntentFilter("Foo"));
- RuntimeEnvironment.application.registerReceiver(expectedReceiver, new IntentFilter("Foo"));
+ ((Application) ApplicationProvider.getApplicationContext())
+ .registerReceiver(expectedReceiver, new IntentFilter("Foo"));
+ ((Application) ApplicationProvider.getApplicationContext())
+ .registerReceiver(expectedReceiver, new IntentFilter("Foo"));
assertTrue(shadowApplication.getReceiversForIntent(new Intent("Foo")).size() == 2);
}
@@ -479,9 +521,10 @@ public class ShadowApplicationTest {
@Test
public void broadcasts_shouldBeLogged() {
Intent broadcastIntent = new Intent("foo");
- RuntimeEnvironment.application.sendBroadcast(broadcastIntent);
+ ((Application) ApplicationProvider.getApplicationContext()).sendBroadcast(broadcastIntent);
- List<Intent> broadcastIntents = shadowOf(RuntimeEnvironment.application).getBroadcastIntents();
+ List<Intent> broadcastIntents =
+ shadowOf((Application) ApplicationProvider.getApplicationContext()).getBroadcastIntents();
assertTrue(broadcastIntents.size() == 1);
assertEquals(broadcastIntent, broadcastIntents.get(0));
}
@@ -489,26 +532,31 @@ public class ShadowApplicationTest {
@Test
public void sendStickyBroadcast() {
Intent broadcastIntent = new Intent("Foo");
- RuntimeEnvironment.application.sendStickyBroadcast(broadcastIntent);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .sendStickyBroadcast(broadcastIntent);
// Register after the broadcast has fired. We should immediately get a sticky event.
TestBroadcastReceiver receiver = new TestBroadcastReceiver();
- RuntimeEnvironment.application.registerReceiver(receiver, new IntentFilter("Foo"));
+ ((Application) ApplicationProvider.getApplicationContext())
+ .registerReceiver(receiver, new IntentFilter("Foo"));
assertTrue(receiver.isSticky);
// Fire the broadcast again, and we should get a non-sticky event.
- RuntimeEnvironment.application.sendStickyBroadcast(broadcastIntent);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .sendStickyBroadcast(broadcastIntent);
assertFalse(receiver.isSticky);
}
@Test
public void shouldRememberResourcesAfterLazilyLoading() throws Exception {
- assertSame(RuntimeEnvironment.application.getResources(), RuntimeEnvironment.application.getResources());
+ assertSame(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ ((Application) ApplicationProvider.getApplicationContext()).getResources());
}
@Test
public void checkPermission_shouldTrackGrantedAndDeniedPermissions() throws Exception {
- Application application = RuntimeEnvironment.application;
+ Application application = (Application) ApplicationProvider.getApplicationContext();
shadowOf(application).grantPermissions("foo", "bar");
shadowOf(application).denyPermissions("foo", "qux");
assertThat(application.checkPermission("foo", -1, -1)).isEqualTo(PERMISSION_DENIED);
@@ -519,7 +567,7 @@ public class ShadowApplicationTest {
@Test
public void startActivity_whenActivityCheckingEnabled_checksPackageManagerResolveInfo() throws Exception {
- Application application = RuntimeEnvironment.application;
+ Application application = (Application) ApplicationProvider.getApplicationContext();
shadowOf(application).checkActivities(true);
String action = "com.does.not.exist.android.app.v2.mobile";
@@ -535,7 +583,7 @@ public class ShadowApplicationTest {
@Test
public void bindServiceShouldAddServiceConnectionToListOfBoundServiceConnections() {
- final Application application = RuntimeEnvironment.application;
+ final Application application = (Application) ApplicationProvider.getApplicationContext();
final ShadowApplication shadowApplication = Shadows.shadowOf(application);
final ServiceConnection expectedServiceConnection = new EmptyServiceConnection();
@@ -549,7 +597,7 @@ public class ShadowApplicationTest {
@Test
public void bindServiceShouldAddServiceConnectionToListOfBoundServiceConnectionsEvenIfServiceUnboundable() {
- final Application application = RuntimeEnvironment.application;
+ final Application application = (Application) ApplicationProvider.getApplicationContext();
final ShadowApplication shadowApplication = Shadows.shadowOf(application);
final ServiceConnection expectedServiceConnection = new EmptyServiceConnection();
final String unboundableAction = "refuse";
@@ -563,7 +611,7 @@ public class ShadowApplicationTest {
@Test
public void unbindServiceShouldRemoveServiceConnectionFromListOfBoundServiceConnections() {
- final Application application = RuntimeEnvironment.application;
+ final Application application = (Application) ApplicationProvider.getApplicationContext();
final ShadowApplication shadowApplication = Shadows.shadowOf(application);
final ServiceConnection expectedServiceConnection = new EmptyServiceConnection();
@@ -580,7 +628,8 @@ public class ShadowApplicationTest {
@Test
public void getThreadScheduler_shouldMatchRobolectricValue() {
- final ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
+ final ShadowApplication shadowApplication =
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext());
assertThat(shadowApplication.getForegroundThreadScheduler()).isSameAs(Robolectric.getForegroundThreadScheduler());
assertThat(shadowApplication.getBackgroundThreadScheduler()).isSameAs(Robolectric.getBackgroundThreadScheduler());
}
@@ -589,7 +638,8 @@ public class ShadowApplicationTest {
public void getForegroundThreadScheduler_shouldMatchRuntimeEnvironment() {
Scheduler s = new Scheduler();
RuntimeEnvironment.setMasterScheduler(s);
- final ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
+ final ShadowApplication shadowApplication =
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext());
assertThat(shadowApplication.getForegroundThreadScheduler()).isSameAs(s);
}
@@ -597,7 +647,8 @@ public class ShadowApplicationTest {
public void getBackgroundThreadScheduler_shouldDifferFromRuntimeEnvironment_byDefault() {
Scheduler s = new Scheduler();
RuntimeEnvironment.setMasterScheduler(s);
- final ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
+ final ShadowApplication shadowApplication =
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext());
assertThat(shadowApplication.getBackgroundThreadScheduler()).isNotSameAs(RuntimeEnvironment.getMasterScheduler());
}
@@ -605,15 +656,22 @@ public class ShadowApplicationTest {
public void getBackgroundThreadScheduler_shouldDifferFromRuntimeEnvironment_withAdvancedScheduling() {
Scheduler s = new Scheduler();
RuntimeEnvironment.setMasterScheduler(s);
- final ShadowApplication shadowApplication = Shadows.shadowOf(RuntimeEnvironment.application);
+ final ShadowApplication shadowApplication =
+ Shadows.shadowOf((Application) ApplicationProvider.getApplicationContext());
assertThat(shadowApplication.getBackgroundThreadScheduler()).isNotSameAs(s);
}
@Test
public void getLatestPopupWindow() {
- PopupWindow pw = new PopupWindow(new LinearLayout(RuntimeEnvironment.application));
-
- pw.showAtLocation(new LinearLayout(RuntimeEnvironment.application), Gravity.CENTER, 0, 0);
+ PopupWindow pw =
+ new PopupWindow(
+ new LinearLayout((Application) ApplicationProvider.getApplicationContext()));
+
+ pw.showAtLocation(
+ new LinearLayout((Application) ApplicationProvider.getApplicationContext()),
+ Gravity.CENTER,
+ 0,
+ 0);
PopupWindow latestPopupWindow = ShadowApplication.getInstance().getLatestPopupWindow();
assertThat(latestPopupWindow).isSameAs(pw);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowArrayAdapterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowArrayAdapterTest.java
index 673bc026c..7067e46b7 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowArrayAdapterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowArrayAdapterTest.java
@@ -3,10 +3,13 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import android.app.Application;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -14,11 +17,9 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowArrayAdapterTest {
private ArrayAdapter<Integer> arrayAdapter;
@@ -28,12 +29,14 @@ public class ShadowArrayAdapterTest {
list.add(2);
list.add(3);
- arrayAdapter = new ArrayAdapter<>(RuntimeEnvironment.application, 0, list);
+ arrayAdapter =
+ new ArrayAdapter<>((Application) ApplicationProvider.getApplicationContext(), 0, list);
}
@Test
public void verifyContext() {
- assertThat(arrayAdapter.getContext()).isSameAs(RuntimeEnvironment.application);
+ assertThat(arrayAdapter.getContext())
+ .isSameAs((Application) ApplicationProvider.getApplicationContext());
}
@Test
@@ -47,8 +50,13 @@ public class ShadowArrayAdapterTest {
@Test
public void usesTextViewResourceIdToSetTextWithinListItemView() throws Exception {
- ListView parent = new ListView(RuntimeEnvironment.application);
- ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(RuntimeEnvironment.application, R.layout.main, R.id.title, new String[] { "first value" });
+ ListView parent = new ListView((Application) ApplicationProvider.getApplicationContext());
+ ArrayAdapter<String> arrayAdapter =
+ new ArrayAdapter<>(
+ (Application) ApplicationProvider.getApplicationContext(),
+ R.layout.main,
+ R.id.title,
+ new String[] {"first value"});
View listItemView = arrayAdapter.getView(0, null, parent);
TextView titleTextView = listItemView.findViewById(R.id.title);
assertEquals("first value", titleTextView.getText().toString());
@@ -56,7 +64,11 @@ public class ShadowArrayAdapterTest {
@Test
public void hasTheCorrectConstructorResourceIDs() {
- ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(RuntimeEnvironment.application, R.id.title, new String[] { "first value" });
+ ArrayAdapter<String> arrayAdapter =
+ new ArrayAdapter<>(
+ (Application) ApplicationProvider.getApplicationContext(),
+ R.id.title,
+ new String[] {"first value"});
//this assertion may look a little backwards since R.id.title is labeled
//textViewResourceId in the constructor parameter list, but the output is correct.
@@ -64,7 +76,8 @@ public class ShadowArrayAdapterTest {
assertThat(Shadows.shadowOf(arrayAdapter).getTextViewResourceId()).isNotEqualTo(R.id.title);
assertThat(Shadows.shadowOf(arrayAdapter).getTextViewResourceId()).isEqualTo(0);
- ArrayAdapter<String> arrayAdapter2 = new ArrayAdapter<>(RuntimeEnvironment.application, R.id.title);
+ ArrayAdapter<String> arrayAdapter2 =
+ new ArrayAdapter<>((Application) ApplicationProvider.getApplicationContext(), R.id.title);
//this assertion may look a little backwards since R.id.title is labeled
//textViewResourceId in the constructor parameter list, but the output is correct.
@@ -72,7 +85,11 @@ public class ShadowArrayAdapterTest {
assertThat(Shadows.shadowOf(arrayAdapter2).getTextViewResourceId()).isNotEqualTo(R.id.title);
assertThat(Shadows.shadowOf(arrayAdapter2).getTextViewResourceId()).isEqualTo(0);
- ArrayAdapter<String> arrayAdapter3 = new ArrayAdapter<>(RuntimeEnvironment.application, R.id.title, Arrays.asList(new String[] { "first value" }));
+ ArrayAdapter<String> arrayAdapter3 =
+ new ArrayAdapter<>(
+ (Application) ApplicationProvider.getApplicationContext(),
+ R.id.title,
+ Arrays.asList(new String[] {"first value"}));
//this assertion may look a little backwards since R.id.title is labeled
//textViewResourceId in the constructor parameter list, but the output is correct.
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAssetManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAssetManagerTest.java
index 10d284f0c..45edb625b 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAssetManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAssetManagerTest.java
@@ -8,11 +8,14 @@ import static org.mockito.Mockito.when;
import static org.robolectric.shadows.ShadowAssetManager.legacyShadowOf;
import static org.robolectric.shadows.ShadowAssetManager.useLegacy;
+import android.app.Application;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.TypedValue;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -23,13 +26,11 @@ import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowResources.ShadowLegacyTheme;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAssetManagerTest {
@Rule
@@ -40,7 +41,7 @@ public class ShadowAssetManagerTest {
@Before
public void setUp() throws Exception {
- resources = RuntimeEnvironment.application.getResources();
+ resources = ((Application) ApplicationProvider.getApplicationContext()).getResources();
assetManager = resources.getAssets();
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncQueryHandlerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncQueryHandlerTest.java
index 3e34f5e76..74a0b3720 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncQueryHandlerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncQueryHandlerTest.java
@@ -4,21 +4,22 @@ import static android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
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;
import org.robolectric.fakes.RoboCursor;
/** Unit tests for {@link ShadowAsyncQueryHandler}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public final class ShadowAsyncQueryHandlerTest {
private static final int TOKEN = 22;
@@ -29,7 +30,8 @@ public final class ShadowAsyncQueryHandlerTest {
@Before
public void setUp() {
- contentResolver = RuntimeEnvironment.application.getContentResolver();
+ contentResolver =
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver();
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncTaskLoaderTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncTaskLoaderTest.java
index 006db88a9..c09082b78 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncTaskLoaderTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncTaskLoaderTest.java
@@ -2,17 +2,18 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.content.AsyncTaskLoader;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAsyncTaskLoaderTest {
private final List<String> transcript = new ArrayList<>();
@@ -64,7 +65,7 @@ public class ShadowAsyncTaskLoaderTest {
private Integer data;
public TestLoader(Integer data) {
- super(RuntimeEnvironment.application);
+ super((Application) ApplicationProvider.getApplicationContext());
this.data = data;
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncTaskTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncTaskTest.java
index b5d2d8098..51c4ee128 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncTaskTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAsyncTaskTest.java
@@ -7,6 +7,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.os.AsyncTask;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
@@ -15,10 +16,9 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.util.Join;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAsyncTaskTest {
private List<String> transcript;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAudioEffectTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAudioEffectTest.java
index c21a876b8..81bf92d40 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAudioEffectTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAudioEffectTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.media.audiofx.AudioEffect;
+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 ShadowAudioEffectTest {
@Test public void queryEffects() {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAudioManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAudioManagerTest.java
index ed5750b6a..6b2114bdf 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAudioManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAudioManagerTest.java
@@ -4,20 +4,22 @@ import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioPlaybackConfiguration;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAudioManagerTest {
- private final AudioManager audioManager = new AudioManager(RuntimeEnvironment.application);
+ private final AudioManager audioManager =
+ new AudioManager((Application) ApplicationProvider.getApplicationContext());
private final AudioManager.OnAudioFocusChangeListener listener = new AudioManager.OnAudioFocusChangeListener() {
@Override
public void onAudioFocusChange(int focusChange) {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAutoCompleteTextViewTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAutoCompleteTextViewTest.java
index 7215cce0c..490afc613 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAutoCompleteTextViewTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAutoCompleteTextViewTest.java
@@ -2,28 +2,31 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.content.Context;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Filter;
import android.widget.Filterable;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowAutoCompleteTextViewTest {
- private final AutoCompleteAdapter adapter = new AutoCompleteAdapter(RuntimeEnvironment.application);
+ private final AutoCompleteAdapter adapter =
+ new AutoCompleteAdapter((Application) ApplicationProvider.getApplicationContext());
@Test
public void shouldInvokeFilter() throws Exception {
Robolectric.getForegroundThreadScheduler().pause();
- AutoCompleteTextView view = new AutoCompleteTextView(RuntimeEnvironment.application);
+ AutoCompleteTextView view =
+ new AutoCompleteTextView((Application) ApplicationProvider.getApplicationContext());
view.setAdapter(adapter);
view.setText("Foo");
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBackupManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBackupManagerTest.java
index b715c7cd1..afca18559 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBackupManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBackupManagerTest.java
@@ -7,10 +7,13 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.backup.BackupManager;
import android.app.backup.RestoreObserver;
import android.app.backup.RestoreSession;
import android.app.backup.RestoreSet;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.truth.Correspondence;
import java.util.Arrays;
import java.util.Objects;
@@ -22,13 +25,11 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
/** Unit tests for {@link ShadowBackupManager}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowBackupManagerTest {
private BackupManager backupManager;
@Mock private TestRestoreObserver restoreObserver;
@@ -39,8 +40,9 @@ public class ShadowBackupManagerTest {
ShadowLooper.pauseMainLooper();
- shadowOf(RuntimeEnvironment.application).grantPermissions(android.Manifest.permission.BACKUP);
- backupManager = new BackupManager(RuntimeEnvironment.application);
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .grantPermissions(android.Manifest.permission.BACKUP);
+ backupManager = new BackupManager((Application) ApplicationProvider.getApplicationContext());
shadowOf(backupManager).addAvailableRestoreSets(123L, Arrays.asList("foo.bar", "bar.baz"));
shadowOf(backupManager).addAvailableRestoreSets(456L, Arrays.asList("hello.world"));
@@ -59,7 +61,10 @@ public class ShadowBackupManagerTest {
// BackupManager is used by creating new instances, but all of them talk to the same
// BackupManagerService in Android, so methods that route through the service will share states.
backupManager.setBackupEnabled(true);
- assertThat(new BackupManager(RuntimeEnvironment.application).isBackupEnabled()).isTrue();
+ assertThat(
+ new BackupManager((Application) ApplicationProvider.getApplicationContext())
+ .isBackupEnabled())
+ .isTrue();
}
@Test
@@ -72,7 +77,8 @@ public class ShadowBackupManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void isBackupEnabled_noPermission_shouldThrowSecurityException() {
- shadowOf(RuntimeEnvironment.application).denyPermissions(android.Manifest.permission.BACKUP);
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .denyPermissions(android.Manifest.permission.BACKUP);
try {
backupManager.isBackupEnabled();
fail("SecurityException should be thrown");
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBaseAdapterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBaseAdapterTest.java
index 9e6c60f73..d0ce5bbea 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBaseAdapterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBaseAdapterTest.java
@@ -7,11 +7,11 @@ import static org.robolectric.Shadows.shadowOf;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
+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 ShadowBaseAdapterTest {
@Test
public void shouldRecordNotifyDataSetChanged() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBatteryManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBatteryManagerTest.java
index 20e4d5270..894f83e75 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBatteryManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBatteryManagerTest.java
@@ -5,16 +5,17 @@ import static android.os.Build.VERSION_CODES.M;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.os.BatteryManager;
+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;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowBatteryManagerTest {
private BatteryManager batteryManager;
@@ -23,8 +24,10 @@ public class ShadowBatteryManagerTest {
@Before
public void before() {
- batteryManager = (BatteryManager) RuntimeEnvironment.application.getSystemService(
- Context.BATTERY_SERVICE);
+ batteryManager =
+ (BatteryManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.BATTERY_SERVICE);
shadowBatteryManager = shadowOf(batteryManager);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBinderTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBinderTest.java
index 14bc47072..009a495b2 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBinderTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBinderTest.java
@@ -7,11 +7,11 @@ import static org.junit.Assert.fail;
import android.os.Binder;
import android.os.Parcel;
import android.os.RemoteException;
+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 ShadowBinderTest {
@Test
public void transactCallsOnTransact() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapDrawableTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapDrawableTest.java
index 96ff2eb4e..f6fafd552 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapDrawableTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapDrawableTest.java
@@ -4,6 +4,7 @@ import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -12,19 +13,20 @@ import android.graphics.ColorMatrixColorFilter;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowBitmapDrawableTest {
- private final Resources resources = RuntimeEnvironment.application.getResources();
+ private final Resources resources =
+ ((Application) ApplicationProvider.getApplicationContext()).getResources();
@Test
public void constructors_shouldSetBitmap() throws Exception {
@@ -96,13 +98,19 @@ public class ShadowBitmapDrawableTest {
@Test
public void constructor_shouldSetTheIntrinsicWidthAndHeightToTheWidthAndHeightOfTheBitmap() throws Exception {
Bitmap bitmap = Bitmap.createBitmap(5, 10, Bitmap.Config.ARGB_8888);
- BitmapDrawable drawable = new BitmapDrawable(RuntimeEnvironment.application.getResources(), bitmap);
+ BitmapDrawable drawable =
+ new BitmapDrawable(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(), bitmap);
assertThat(drawable.getIntrinsicWidth()).isEqualTo(5);
assertThat(drawable.getIntrinsicHeight()).isEqualTo(10);
}
@Test
public void constructor_shouldAcceptNullBitmap() throws Exception {
- assertThat(new BitmapDrawable(RuntimeEnvironment.application.getResources(), (Bitmap) null)).isNotNull();
+ assertThat(
+ new BitmapDrawable(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ (Bitmap) null))
+ .isNotNull();
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapFactoryTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapFactoryTest.java
index 1a9dcdd7d..ae8e71c7c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapFactoryTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapFactoryTest.java
@@ -5,11 +5,14 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.net.Uri;
import android.provider.MediaStore;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -17,14 +20,15 @@ import java.io.InputStream;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowBitmapFactoryTest {
@Test
public void decodeResource_shouldSetDescriptionAndCreatedFrom() throws Exception {
- Bitmap bitmap = BitmapFactory.decodeResource(RuntimeEnvironment.application.getResources(), R.drawable.an_image);
+ Bitmap bitmap =
+ BitmapFactory.decodeResource(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ R.drawable.an_image);
ShadowBitmap shadowBitmap = shadowOf(bitmap);
assertEquals("Bitmap for resource:org.robolectric:drawable/an_image", shadowBitmap.getDescription());
assertEquals(R.drawable.an_image, shadowBitmap.getCreatedFromResId());
@@ -34,21 +38,31 @@ public class ShadowBitmapFactoryTest {
@Test
public void decodeResource_shouldSetDefaultBitmapConfig() throws Exception {
- Bitmap bitmap = BitmapFactory.decodeResource(RuntimeEnvironment.application.getResources(), R.drawable.an_image);
+ Bitmap bitmap =
+ BitmapFactory.decodeResource(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ R.drawable.an_image);
assertThat(bitmap.getConfig()).isEqualTo(Bitmap.Config.ARGB_8888);
assertThat(bitmap.getRowBytes()).isNotEqualTo(0);
}
@Test
public void withResId0_decodeResource_shouldReturnNull() throws Exception {
- assertThat(BitmapFactory.decodeResource(RuntimeEnvironment.application.getResources(), 0)).isNull();
+ assertThat(
+ BitmapFactory.decodeResource(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(), 0))
+ .isNull();
}
@Test
public void decodeResource_shouldPassABitmapConfig() throws Exception {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ALPHA_8;
- Bitmap bitmap = BitmapFactory.decodeResource(RuntimeEnvironment.application.getResources(), R.drawable.an_image, options);
+ Bitmap bitmap =
+ BitmapFactory.decodeResource(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ R.drawable.an_image,
+ options);
assertThat(bitmap.getConfig()).isEqualTo(Bitmap.Config.ALPHA_8);
}
@@ -64,7 +78,10 @@ public class ShadowBitmapFactoryTest {
@Test
public void decodeStream_shouldSetDescriptionAndCreatedFrom() throws Exception {
- InputStream inputStream = RuntimeEnvironment.application.getContentResolver().openInputStream(Uri.parse("content:/path"));
+ InputStream inputStream =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getContentResolver()
+ .openInputStream(Uri.parse("content:/path"));
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
ShadowBitmap shadowBitmap = shadowOf(bitmap);
assertEquals("Bitmap for content:/path", shadowBitmap.getDescription());
@@ -87,7 +104,10 @@ public class ShadowBitmapFactoryTest {
@Test
public void decodeStream_shouldSetDescriptionWithNullOptions() throws Exception {
- InputStream inputStream = RuntimeEnvironment.application.getContentResolver().openInputStream(Uri.parse("content:/path"));
+ InputStream inputStream =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getContentResolver()
+ .openInputStream(Uri.parse("content:/path"));
Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, null);
assertEquals("Bitmap for content:/path", shadowOf(bitmap).getDescription());
assertEquals(100, bitmap.getWidth());
@@ -98,7 +118,10 @@ public class ShadowBitmapFactoryTest {
public void decodeResource_shouldGetWidthAndHeightFromHints() throws Exception {
ShadowBitmapFactory.provideWidthAndHeightHints(R.drawable.an_image, 123, 456);
- Bitmap bitmap = BitmapFactory.decodeResource(RuntimeEnvironment.application.getResources(), R.drawable.an_image);
+ Bitmap bitmap =
+ BitmapFactory.decodeResource(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ R.drawable.an_image);
assertEquals("Bitmap for resource:org.robolectric:drawable/an_image", shadowOf(bitmap).getDescription());
assertEquals(123, bitmap.getWidth());
assertEquals(456, bitmap.getHeight());
@@ -108,16 +131,29 @@ public class ShadowBitmapFactoryTest {
public void decodeResource_canTakeOptions() throws Exception {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 100;
- Bitmap bitmap = BitmapFactory.decodeResource(RuntimeEnvironment.application.getResources(), R.drawable.an_image, options);
+ Bitmap bitmap =
+ BitmapFactory.decodeResource(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ R.drawable.an_image,
+ options);
assertEquals(true, shadowOf(bitmap).getDescription().contains("inSampleSize=100"));
}
@Test
public void decodeResourceStream_canTakeOptions() throws Exception {
BitmapFactory.Options options = new BitmapFactory.Options();
- InputStream inputStream = RuntimeEnvironment.application.getContentResolver().openInputStream(Uri.parse("content:/path"));
+ InputStream inputStream =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getContentResolver()
+ .openInputStream(Uri.parse("content:/path"));
options.inSampleSize = 100;
- Bitmap bitmap = BitmapFactory.decodeResourceStream(RuntimeEnvironment.application.getResources(), null, inputStream, null, options);
+ Bitmap bitmap =
+ BitmapFactory.decodeResourceStream(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ null,
+ inputStream,
+ null,
+ options);
assertEquals(true, shadowOf(bitmap).getDescription().contains("inSampleSize=100"));
}
@@ -145,7 +181,10 @@ public class ShadowBitmapFactoryTest {
public void decodeUri_shouldGetWidthAndHeightFromHints() throws Exception {
ShadowBitmapFactory.provideWidthAndHeightHints(Uri.parse("content:/path"), 123, 456);
- Bitmap bitmap = MediaStore.Images.Media.getBitmap(RuntimeEnvironment.application.getContentResolver(), Uri.parse("content:/path"));
+ Bitmap bitmap =
+ MediaStore.Images.Media.getBitmap(
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver(),
+ Uri.parse("content:/path"));
assertEquals("Bitmap for content:/path", shadowOf(bitmap).getDescription());
assertEquals(123, bitmap.getWidth());
assertEquals(456, bitmap.getHeight());
@@ -199,7 +238,10 @@ public class ShadowBitmapFactoryTest {
public void decodeStream_shouldGetWidthAndHeightFromHints() throws Exception {
ShadowBitmapFactory.provideWidthAndHeightHints(Uri.parse("content:/path"), 123, 456);
- InputStream inputStream = RuntimeEnvironment.application.getContentResolver().openInputStream(Uri.parse("content:/path"));
+ InputStream inputStream =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getContentResolver()
+ .openInputStream(Uri.parse("content:/path"));
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
assertEquals("Bitmap for content:/path", shadowOf(bitmap).getDescription());
assertEquals(123, bitmap.getWidth());
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapRegionDecoderTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapRegionDecoderTest.java
index 9b2644752..c502811e9 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapRegionDecoderTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapRegionDecoderTest.java
@@ -2,10 +2,13 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Rect;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.io.ByteStreams;
import java.awt.image.BufferedImage;
import java.io.File;
@@ -18,11 +21,9 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(qualifiers = "hdpi")
public class ShadowBitmapRegionDecoderTest {
@@ -73,11 +74,17 @@ public class ShadowBitmapRegionDecoderTest {
}
private static InputStream getImageInputStream() {
- return RuntimeEnvironment.application.getResources().openRawResource(R.drawable.robolectric);
+ return ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .openRawResource(R.drawable.robolectric);
}
private static FileDescriptor getImageFd() throws Exception {
- return RuntimeEnvironment.application.getResources().getAssets().openFd("robolectric.png").getFileDescriptor();
+ return ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getAssets()
+ .openFd("robolectric.png")
+ .getFileDescriptor();
}
private String getGeneratedImageFile() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapTest.java
index 45405fc98..b6e672454 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBitmapTest.java
@@ -15,6 +15,7 @@ import android.graphics.Paint;
import android.os.Build;
import android.os.Parcel;
import android.util.DisplayMetrics;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
@@ -22,11 +23,10 @@ import java.nio.ShortBuffer;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowBitmapTest {
@Test
public void shouldCreateScaledBitmap() throws Exception {
@@ -580,6 +580,61 @@ public class ShadowBitmapTest {
original.reconfigure(100, 100, Bitmap.Config.ARGB_8888);
}
+ @Config(sdk = Build.VERSION_CODES.KITKAT)
+ @Test
+ public void setPremultiplied() {
+ Bitmap original = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+ assertThat(original.isPremultiplied()).isFalse();
+ original.setPremultiplied(true);
+ assertThat(original.isPremultiplied()).isTrue();
+ original.setPremultiplied(false);
+ assertThat(original.isPremultiplied()).isFalse();
+ }
+
+ @Test
+ public void sameAs_bitmapsDifferentWidth() {
+ Bitmap original1 = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+ Bitmap original2 = Bitmap.createBitmap(101, 100, Bitmap.Config.ARGB_8888);
+ assertThat(original1.sameAs(original2)).isFalse();
+ }
+
+ @Test
+ public void sameAs_bitmapsDifferentHeight() {
+ Bitmap original1 = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+ Bitmap original2 = Bitmap.createBitmap(100, 101, Bitmap.Config.ARGB_8888);
+ assertThat(original1.sameAs(original2)).isFalse();
+ }
+
+ @Test
+ public void sameAs_bitmapsDifferentConfig() {
+ Bitmap original1 = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
+ Bitmap original2 = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_4444);
+ assertThat(original1.sameAs(original2)).isFalse();
+ }
+
+ @Test
+ public void sameAs_bitmapsDifferentPixels() {
+ int[] pixels1 = new int[] {0, 1, 2, 3};
+ Bitmap original1 = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888);
+ original1.setPixels(pixels1, 0, 1, 0, 0, 2, 2);
+
+ int[] pixels2 = new int[] {3, 2, 1, 0};
+ Bitmap original2 = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888);
+ original2.setPixels(pixels2, 0, 1, 0, 0, 2, 2);
+ assertThat(original1.sameAs(original2)).isFalse();
+ }
+
+ @Test
+ public void sameAs_bitmapsSamePixels() {
+ int[] pixels = new int[] {0, 1, 2, 3};
+ Bitmap original1 = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888);
+ original1.setPixels(pixels, 0, 1, 0, 0, 2, 2);
+
+ Bitmap original2 = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888);
+ original2.setPixels(pixels, 0, 1, 0, 0, 2, 2);
+ assertThat(original1.sameAs(original2)).isTrue();
+ }
+
private static Bitmap create(String name) {
Bitmap bitmap = Shadow.newInstanceOf(Bitmap.class);
shadowOf(bitmap).appendDescription(name);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothAdapterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothAdapterTest.java
index f3b931e4c..88fdf8a35 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothAdapterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothAdapterTest.java
@@ -7,17 +7,18 @@ import static org.robolectric.Shadows.shadowOf;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.UUID;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowBluetoothAdapterTest {
private BluetoothAdapter bluetoothAdapter;
private ShadowBluetoothAdapter shadowBluetoothAdapter;
@@ -144,11 +145,24 @@ public class ShadowBluetoothAdapterTest {
@Test
public void insecureRfcomm_notNull() throws Exception {
assertThat(
- bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(
- "serviceName", UUID.randomUUID()))
+ bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(
+ "serviceName", UUID.randomUUID()))
.isNotNull();
}
+ @Test
+ public void canGetProfileConnectionState() throws Exception {
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ assertThat(adapter.getProfileConnectionState(BluetoothProfile.HEADSET))
+ .isEqualTo(BluetoothProfile.STATE_DISCONNECTED);
+ shadowOf(adapter)
+ .setProfileConnectionState(BluetoothProfile.HEADSET, BluetoothProfile.STATE_CONNECTED);
+ assertThat(adapter.getProfileConnectionState(BluetoothProfile.HEADSET))
+ .isEqualTo(BluetoothProfile.STATE_CONNECTED);
+ assertThat(adapter.getProfileConnectionState(BluetoothProfile.A2DP))
+ .isEqualTo(BluetoothProfile.STATE_DISCONNECTED);
+ }
+
private BluetoothAdapter.LeScanCallback newLeScanCallback() {
return new BluetoothAdapter.LeScanCallback() {
@Override
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothDeviceTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothDeviceTest.java
index 48caf1627..cd65a6d93 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothDeviceTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothDeviceTest.java
@@ -6,17 +6,18 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGattCallback;
import android.os.ParcelUuid;
+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;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowBluetoothDeviceTest {
private static final String MOCK_MAC_ADDRESS = "00:11:22:33:AA:BB";
@@ -34,8 +35,8 @@ public class ShadowBluetoothDeviceTest {
BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(MOCK_MAC_ADDRESS);
ParcelUuid[] uuids =
new ParcelUuid[] {
- ParcelUuid.fromString("00000000-1111-2222-3333-000000000011"),
- ParcelUuid.fromString("00000000-1111-2222-3333-0000000000aa")
+ ParcelUuid.fromString("00000000-1111-2222-3333-000000000011"),
+ ParcelUuid.fromString("00000000-1111-2222-3333-0000000000aa")
};
shadowOf(device).setUuids(uuids);
@@ -94,8 +95,10 @@ public class ShadowBluetoothDeviceTest {
public void connectGatt_doesntCrash() throws Exception {
BluetoothDevice bluetoothDevice = ShadowBluetoothDevice.newInstance(MOCK_MAC_ADDRESS);
assertThat(
- bluetoothDevice.connectGatt(
- RuntimeEnvironment.application, false, new BluetoothGattCallback() {}))
+ bluetoothDevice.connectGatt(
+ (Application) ApplicationProvider.getApplicationContext(),
+ false,
+ new BluetoothGattCallback() {}))
.isNotNull();
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothGattTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothGattTest.java
index 96594d70c..90d5f2810 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothGattTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothGattTest.java
@@ -5,13 +5,13 @@ import static com.google.common.truth.Truth.assertThat;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** Tests for {@link ShadowBluetoothGatt}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = JELLY_BEAN_MR2)
public class ShadowBluetoothGattTest {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothManagerTest.java
index 1793012ad..50bccaa05 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothManagerTest.java
@@ -3,22 +3,26 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
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;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = JELLY_BEAN_MR2)
public class ShadowBluetoothManagerTest {
- private final BluetoothManager manager = (BluetoothManager) RuntimeEnvironment.application.getSystemService(Context.BLUETOOTH_SERVICE);
+ private final BluetoothManager manager =
+ (BluetoothManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.BLUETOOTH_SERVICE);
- @Test
- public void getAdapter_shouldReturnBluetoothAdapter() {
- assertThat(manager.getAdapter()).isSameAs(BluetoothAdapter.getDefaultAdapter());
- }
+ @Test
+ public void getAdapter_shouldReturnBluetoothAdapter() {
+ assertThat(manager.getAdapter()).isSameAs(BluetoothAdapter.getDefaultAdapter());
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothSocketTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothSocketTest.java
new file mode 100644
index 000000000..22560ca46
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothSocketTest.java
@@ -0,0 +1,44 @@
+package org.robolectric.shadows;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.bluetooth.BluetoothSocket;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import java.io.InputStream;
+import java.util.Arrays;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.shadow.api.Shadow;
+
+@RunWith(AndroidJUnit4.class)
+public class ShadowBluetoothSocketTest {
+ BluetoothSocket bluetoothSocket;
+
+ private static final byte[] DATA = new byte[] {1, 2, 3, 42, 96, 127};
+
+ @Before
+ public void setUp() throws Exception {
+ bluetoothSocket = Shadow.newInstanceOf(BluetoothSocket.class);
+ }
+
+ @Test
+ public void getInputStreamFeeder() throws Exception {
+ shadowOf(bluetoothSocket).getInputStreamFeeder().write(DATA);
+
+ InputStream inputStream = bluetoothSocket.getInputStream();
+ byte[] b = new byte[1024];
+ int len = inputStream.read(b);
+ assertThat(Arrays.copyOf(b, len)).isEqualTo(DATA);
+ }
+
+ @Test
+ public void getOutputStreamSink() throws Exception {
+ bluetoothSocket.getOutputStream().write(DATA);
+
+ byte[] b = new byte[1024];
+ int len = shadowOf(bluetoothSocket).getOutputStreamSink().read(b);
+ assertThat(Arrays.copyOf(b, len)).isEqualTo(DATA);
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBroadcastPendingResultTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBroadcastPendingResultTest.java
index 0bccec86f..16a1c4861 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBroadcastPendingResultTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBroadcastPendingResultTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.os.Bundle;
+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 ShadowBroadcastPendingResultTest {
@Test
public void testCreate() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBuildTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBuildTest.java
index dd4108b57..9688830fb 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBuildTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBuildTest.java
@@ -5,12 +5,12 @@ import static com.google.common.truth.Truth.assertThat;
import android.os.Build;
import android.os.Build.VERSION;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowBuildTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBundleTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBundleTest.java
index e809abe5a..4a079c0c4 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBundleTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBundleTest.java
@@ -4,12 +4,12 @@ import static com.google.common.truth.Truth.assertThat;
import android.os.Bundle;
import android.os.Parcelable;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowBundleTest {
private final Bundle bundle = new Bundle();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraCharacteristicsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraCharacteristicsTest.java
new file mode 100644
index 000000000..195b6394f
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraCharacteristicsTest.java
@@ -0,0 +1,47 @@
+package org.robolectric.shadows;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraCharacteristics.Key;
+import android.os.Build.VERSION_CODES;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+/** Tests for {@link ShadowCameraCharacteristics}. */
+@Config(minSdk = VERSION_CODES.LOLLIPOP)
+@RunWith(AndroidJUnit4.class)
+public class ShadowCameraCharacteristicsTest {
+
+ private final Key key0 = new Key("key0", Integer.class);
+ private final CameraCharacteristics cameraCharacteristics =
+ ShadowCameraCharacteristics.newCameraCharacteristics();
+
+ @Test
+ public void testSetExistingKey() {
+ shadowOf(cameraCharacteristics).set(key0, 1);
+
+ try {
+ shadowOf(cameraCharacteristics).set(key0, 1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testGetUnrecognizedKey() {
+ assertThat(cameraCharacteristics.get(key0)).isNull();
+ }
+
+ @Test
+ public void testGetRecognizedKey() {
+ shadowOf(cameraCharacteristics).set(key0, 1);
+
+ assertThat(cameraCharacteristics.get(key0)).isEqualTo(1);
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraManagerTest.java
new file mode 100644
index 000000000..6c6a9f320
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraManagerTest.java
@@ -0,0 +1,114 @@
+package org.robolectric.shadows;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.app.Application;
+import android.content.Context;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.os.Build.VERSION_CODES;
+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.annotation.Config;
+
+/** Tests for {@link ShadowCameraManager}. */
+@Config(minSdk = VERSION_CODES.LOLLIPOP)
+@RunWith(AndroidJUnit4.class)
+public class ShadowCameraManagerTest {
+
+ private static final String CAMERA_ID_0 = "cameraId0";
+ private static final String CAMERA_ID_1 = "cameraId1";
+
+ private final CameraManager cameraManager =
+ (CameraManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.CAMERA_SERVICE);
+
+ private final CameraCharacteristics characteristics =
+ ShadowCameraCharacteristics.newCameraCharacteristics();
+
+ @Test
+ public void testAddCameraNullCameraId() {
+ try {
+ shadowOf(cameraManager).addCamera(null, characteristics);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testAddCameraNullCharacteristics() {
+ try {
+ shadowOf(cameraManager).addCamera(CAMERA_ID_0, null);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testAddCameraExistingId() {
+ shadowOf(cameraManager).addCamera(CAMERA_ID_0, characteristics);
+
+ try {
+ shadowOf(cameraManager).addCamera(CAMERA_ID_0, characteristics);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testGetCameraIdListNoCameras() throws CameraAccessException {
+ assertThat(cameraManager.getCameraIdList()).isEmpty();
+ }
+
+ @Test
+ public void testGetCameraIdListSingleCamera() throws CameraAccessException {
+ shadowOf(cameraManager).addCamera(CAMERA_ID_0, characteristics);
+
+ assertThat(cameraManager.getCameraIdList()).asList().containsExactly(CAMERA_ID_0);
+ }
+
+ @Test
+ public void testGetCameraIdListInOrderOfAdd() throws CameraAccessException {
+ shadowOf(cameraManager).addCamera(CAMERA_ID_0, characteristics);
+ shadowOf(cameraManager).addCamera(CAMERA_ID_1, characteristics);
+
+ assertThat(cameraManager.getCameraIdList()[0]).isEqualTo(CAMERA_ID_0);
+ assertThat(cameraManager.getCameraIdList()[1]).isEqualTo(CAMERA_ID_1);
+ }
+
+ @Test
+ public void testGetCameraCharacteristicsNullCameraId() throws CameraAccessException {
+ try {
+ cameraManager.getCameraCharacteristics(null);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testGetCameraCharacteristicsUnrecognizedCameraId() throws CameraAccessException {
+ try {
+ cameraManager.getCameraCharacteristics(CAMERA_ID_0);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testGetCameraCharacteristicsRecognizedCameraId() throws CameraAccessException {
+ shadowOf(cameraManager).addCamera(CAMERA_ID_0, characteristics);
+
+ assertThat(cameraManager.getCameraCharacteristics(CAMERA_ID_0)).isSameAs(characteristics);
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraParametersTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraParametersTest.java
index 56cc9072d..f69619c34 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraParametersTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraParametersTest.java
@@ -4,37 +4,35 @@ import static com.google.common.truth.Truth.assertThat;
import android.graphics.ImageFormat;
import android.hardware.Camera;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.Lists;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowCameraParametersTest {
private Camera.Parameters parameters;
- private ShadowCamera.ShadowParameters shadowParameters;
@Before
public void setUp() throws Exception {
parameters = Shadow.newInstanceOf(Camera.Parameters.class);
- shadowParameters = Shadows.shadowOf(parameters);
}
@Test
public void testPictureSize() throws Exception {
- assertThat(shadowParameters.getPictureHeight()).isNotEqualTo((600));
- assertThat(shadowParameters.getPictureWidth()).isNotEqualTo((800));
+ assertThat(Shadows.shadowOf(parameters).getPictureHeight()).isNotEqualTo(600);
+ assertThat(Shadows.shadowOf(parameters).getPictureWidth()).isNotEqualTo(800);
parameters.setPictureSize(800, 600);
Camera.Size pictureSize = parameters.getPictureSize();
assertThat(pictureSize.width).isEqualTo(800);
assertThat(pictureSize.height).isEqualTo(600);
- assertThat(shadowParameters.getPictureHeight()).isEqualTo(600);
- assertThat(shadowParameters.getPictureWidth()).isEqualTo(800);
+ assertThat(Shadows.shadowOf(parameters).getPictureHeight()).isEqualTo(600);
+ assertThat(Shadows.shadowOf(parameters).getPictureWidth()).isEqualTo(800);
}
@Test
@@ -58,21 +56,21 @@ public class ShadowCameraParametersTest {
@Test
public void testPreviewSize() throws Exception {
- assertThat(shadowParameters.getPreviewWidth()).isNotEqualTo((320));
- assertThat(shadowParameters.getPreviewHeight()).isNotEqualTo((240));
+ assertThat(Shadows.shadowOf(parameters).getPreviewWidth()).isNotEqualTo(320);
+ assertThat(Shadows.shadowOf(parameters).getPreviewHeight()).isNotEqualTo(240);
parameters.setPreviewSize(320, 240);
Camera.Size size = parameters.getPreviewSize();
assertThat(size.width).isEqualTo(320);
assertThat(size.height).isEqualTo(240);
- assertThat(shadowParameters.getPreviewWidth()).isEqualTo(320);
- assertThat(shadowParameters.getPreviewHeight()).isEqualTo(240);
+ assertThat(Shadows.shadowOf(parameters).getPreviewWidth()).isEqualTo(320);
+ assertThat(Shadows.shadowOf(parameters).getPreviewHeight()).isEqualTo(240);
}
@Test
public void testPreviewFormat() throws Exception {
- assertThat(shadowParameters.getPreviewFormat()).isEqualTo(ImageFormat.NV21);
+ assertThat(parameters.getPreviewFormat()).isEqualTo(ImageFormat.NV21);
parameters.setPreviewFormat(ImageFormat.JPEG);
- assertThat(shadowParameters.getPreviewFormat()).isEqualTo(ImageFormat.JPEG);
+ assertThat(parameters.getPreviewFormat()).isEqualTo(ImageFormat.JPEG);
}
@Test
@@ -110,6 +108,24 @@ public class ShadowCameraParametersTest {
}
@Test
+ public void testInitSupportedPreviewSizes() throws Exception {
+ Shadows.shadowOf(parameters).initSupportedPreviewSizes();
+ assertThat(parameters.getSupportedPreviewSizes()).isNotNull();
+ assertThat(parameters.getSupportedPreviewSizes()).isEmpty();
+ }
+
+ @Test
+ public void testAddSupportedPreviewSizes() throws Exception {
+ Shadows.shadowOf(parameters).initSupportedPreviewSizes();
+ Shadows.shadowOf(parameters).addSupportedPreviewSize(320, 240);
+ List<Camera.Size> supportedSizes = parameters.getSupportedPreviewSizes();
+ assertThat(supportedSizes).isNotNull();
+ assertThat(supportedSizes).hasSize(1);
+ assertThat(supportedSizes.get(0).width).isEqualTo(320);
+ assertThat(supportedSizes.get(0).height).isEqualTo(240);
+ }
+
+ @Test
public void testGetSupportedPreviewFpsRange() throws Exception {
List<int[]> supportedRanges = parameters.getSupportedPreviewFpsRange();
assertThat(supportedRanges).isNotNull();
@@ -150,9 +166,9 @@ public class ShadowCameraParametersTest {
@Test
public void testSetSupportedFocusModes() {
- shadowParameters.setSupportedFocusModes("foo", "bar");
+ Shadows.shadowOf(parameters).setSupportedFocusModes("foo", "bar");
assertThat(parameters.getSupportedFocusModes()).isEqualTo(Lists.newArrayList("foo", "bar"));
- shadowParameters.setSupportedFocusModes("baz");
+ Shadows.shadowOf(parameters).setSupportedFocusModes("baz");
assertThat(parameters.getSupportedFocusModes()).isEqualTo(Lists.newArrayList("baz"));
}
@@ -161,4 +177,24 @@ public class ShadowCameraParametersTest {
parameters.setFocusMode("foo");
assertThat(parameters.getFocusMode()).isEqualTo("foo");
}
+
+ @Test
+ public void testGetSupportedFlashModesDefaultValue() {
+ List<String> supportedFlashModes = parameters.getSupportedFlashModes();
+ assertThat(supportedFlashModes).isEmpty();
+ }
+
+ @Test
+ public void testSetSupportedFlashModes() {
+ Shadows.shadowOf(parameters).setSupportedFlashModes("foo", "bar");
+ assertThat(parameters.getSupportedFlashModes()).containsExactly("foo", "bar").inOrder();
+ Shadows.shadowOf(parameters).setSupportedFlashModes("baz");
+ assertThat(parameters.getSupportedFlashModes()).containsExactly("baz");
+ }
+
+ @Test
+ public void testSetAndGetFlashMode() {
+ parameters.setFlashMode("foo");
+ assertThat(parameters.getFlashMode()).isEqualTo("foo");
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraSizeTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraSizeTest.java
index adf764864..fbec34866 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraSizeTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraSizeTest.java
@@ -3,13 +3,13 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.hardware.Camera;
+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.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowCameraSizeTest {
private Camera.Size cameraSize;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraTest.java
index 658c5f683..a7687e4da 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCameraTest.java
@@ -10,14 +10,14 @@ import android.graphics.Rect;
import android.hardware.Camera;
import android.view.Surface;
import android.view.SurfaceHolder;
+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.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowCameraTest {
private Camera camera;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCanvasTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCanvasTest.java
index 1f37b44db..6aae0dd30 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCanvasTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCanvasTest.java
@@ -14,13 +14,13 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
+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.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowCanvasTest {
private Bitmap targetBitmap;
private Bitmap imageBitmap;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCaptioningManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCaptioningManagerTest.java
index 03f32ad55..210849c73 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCaptioningManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCaptioningManagerTest.java
@@ -1,53 +1,93 @@
package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.view.accessibility.CaptioningManager;
+import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
+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;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
/** Tests for the ShadowCaptioningManager. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = 19)
public final class ShadowCaptioningManagerTest {
+
+ @Mock private CaptioningChangeListener captioningChangeListener;
+
private CaptioningManager captioningManager;
- private ShadowCaptioningManager shadowCaptioningManager;
@Before
public void setUp() {
+ MockitoAnnotations.initMocks(this);
captioningManager =
(CaptioningManager)
- RuntimeEnvironment.application.getSystemService(Context.CAPTIONING_SERVICE);
- shadowCaptioningManager = shadowOf(captioningManager);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.CAPTIONING_SERVICE);
}
@Test
public void setEnabled_true() {
assertThat(captioningManager.isEnabled()).isFalse();
- shadowCaptioningManager.setEnabled(true);
+ shadowOf(captioningManager).setEnabled(true);
assertThat(captioningManager.isEnabled()).isTrue();
}
@Test
public void setEnabled_false() {
- shadowCaptioningManager.setEnabled(false);
+ shadowOf(captioningManager).setEnabled(false);
assertThat(captioningManager.isEnabled()).isFalse();
}
@Test
- public void setFontScale() {
+ public void setFontScale_changesValueOfGetFontScale() {
float fontScale = 1.5f;
- shadowCaptioningManager.setFontScale(fontScale);
+ shadowOf(captioningManager).setFontScale(fontScale);
assertThat(captioningManager.getFontScale()).isWithin(0.001f).of(fontScale);
}
+
+ @Test
+ public void setFontScale_notifiesObservers() {
+ float fontScale = 1.5f;
+ captioningManager.addCaptioningChangeListener(captioningChangeListener);
+
+ shadowOf(captioningManager).setFontScale(fontScale);
+
+ verify(captioningChangeListener).onFontScaleChanged(fontScale);
+ }
+
+ @Test
+ public void addCaptioningChangeListener_doesNotRegisterSameListenerTwice() {
+ float fontScale = 1.5f;
+ captioningManager.addCaptioningChangeListener(captioningChangeListener);
+
+ captioningManager.addCaptioningChangeListener(captioningChangeListener);
+
+ shadowOf(captioningManager).setFontScale(fontScale);
+ verify(captioningChangeListener).onFontScaleChanged(fontScale);
+ }
+
+ @Test
+ public void removeCaptioningChangeListener_unregistersFontScaleListener() {
+ captioningManager.addCaptioningChangeListener(captioningChangeListener);
+
+ captioningManager.removeCaptioningChangeListener(captioningChangeListener);
+
+ shadowOf(captioningManager).setFontScale(1.5f);
+ verifyZeroInteractions(captioningChangeListener);
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCarrierConfigManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCarrierConfigManagerTest.java
new file mode 100644
index 000000000..24336eeb6
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCarrierConfigManagerTest.java
@@ -0,0 +1,57 @@
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.M;
+import static com.google.common.truth.Truth.assertThat;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.app.Application;
+import android.content.Context;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+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.annotation.Config;
+
+/** Junit test for {@link ShadowCarrierConfigManager}. */
+@RunWith(AndroidJUnit4.class)
+@Config(minSdk = M)
+public class ShadowCarrierConfigManagerTest {
+
+ private CarrierConfigManager carrierConfigManager;
+
+ private static final int TEST_ID = 123;
+
+ @Before
+ public void setUp() {
+ carrierConfigManager =
+ (CarrierConfigManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ }
+
+ @Test
+ public void getConfigForSubId_shouldReturnNonNullValue() throws Exception {
+ PersistableBundle persistableBundle = carrierConfigManager.getConfigForSubId(-1);
+ assertThat(persistableBundle).isNotNull();
+ }
+
+ @Test
+ public void testGetConfigForSubId() throws Exception {
+ PersistableBundle persistableBundle = new PersistableBundle();
+ persistableBundle.putString("key1", "test");
+ persistableBundle.putInt("key2", 100);
+ persistableBundle.putBoolean("key3", true);
+
+ shadowOf(carrierConfigManager).setConfigForSubId(TEST_ID, persistableBundle);
+
+ PersistableBundle verifyBundle = carrierConfigManager.getConfigForSubId(TEST_ID);
+ assertThat(verifyBundle).isNotNull();
+
+ assertThat(verifyBundle.get("key1")).isEqualTo("test");
+ assertThat(verifyBundle.getInt("key2")).isEqualTo(100);
+ assertThat(verifyBundle.getBoolean("key3")).isTrue();
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCheckBoxTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCheckBoxTest.java
index 462fcc755..b3a92f2cf 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCheckBoxTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCheckBoxTest.java
@@ -2,17 +2,18 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.widget.CheckBox;
+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 ShadowCheckBoxTest {
@Test
public void testWorks() throws Exception {
- CheckBox checkBox = new CheckBox(RuntimeEnvironment.application);
+ CheckBox checkBox = new CheckBox((Application) ApplicationProvider.getApplicationContext());
assertThat(checkBox.isChecked()).isFalse();
checkBox.setChecked(true);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCheckedTextViewTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCheckedTextViewTest.java
index 02a8bc357..851ce30a9 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCheckedTextViewTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCheckedTextViewTest.java
@@ -3,21 +3,23 @@ package org.robolectric.shadows;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import android.app.Application;
import android.widget.CheckedTextView;
+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 ShadowCheckedTextViewTest {
private CheckedTextView checkedTextView;
@Before
public void beforeTests() {
- checkedTextView = new CheckedTextView(RuntimeEnvironment.application);
+ checkedTextView =
+ new CheckedTextView((Application) ApplicationProvider.getApplicationContext());
}
@Test
@@ -39,7 +41,8 @@ public class ShadowCheckedTextViewTest {
}
@Test public void toggle_shouldChangeCheckedness() throws Exception {
- CheckedTextView view = new CheckedTextView(RuntimeEnvironment.application);
+ CheckedTextView view =
+ new CheckedTextView((Application) ApplicationProvider.getApplicationContext());
assertFalse(view.isChecked());
view.toggle();
assertTrue(view.isChecked());
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowChoreographerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowChoreographerTest.java
index e543034f2..1cfec00f3 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowChoreographerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowChoreographerTest.java
@@ -7,12 +7,12 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.view.Choreographer;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.util.TimeUtils;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowChoreographerTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowClipboardManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowClipboardManagerTest.java
index 9a0359f45..1c1840714 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowClipboardManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowClipboardManagerTest.java
@@ -6,22 +6,26 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import android.app.Application;
import android.content.ClipData;
import android.content.ClipboardManager;
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 ShadowClipboardManagerTest {
private ClipboardManager clipboardManager;
@Before public void setUp() throws Exception {
- clipboardManager = (ClipboardManager) RuntimeEnvironment.application.getSystemService(Context.CLIPBOARD_SERVICE);
+ clipboardManager =
+ (ClipboardManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.CLIPBOARD_SERVICE);
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowColorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowColorTest.java
index 5edf1a15d..e39743d55 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowColorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowColorTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.graphics.Color;
+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 ShadowColorTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowConfigurationTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowConfigurationTest.java
index ef9b7fc0f..5d7513710 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowConfigurationTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowConfigurationTest.java
@@ -5,14 +5,14 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.res.Configuration;
import android.os.Build;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowConfigurationTest {
private Configuration configuration;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowConnectivityManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowConnectivityManagerTest.java
index b9bc649ab..9ab11fe57 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowConnectivityManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowConnectivityManagerTest.java
@@ -1,9 +1,11 @@
package org.robolectric.shadows;
+import static android.os.Build.VERSION_CODES.KITKAT;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static android.os.Build.VERSION_CODES.M;
+import static android.os.Build.VERSION_CODES.N;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -12,29 +14,30 @@ import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
+import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
+import android.provider.Settings;
import android.telephony.TelephonyManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowConnectivityManagerTest {
private ConnectivityManager connectivityManager;
private ShadowNetworkInfo shadowOfActiveNetworkInfo;
- private ShadowConnectivityManager shadowConnectivityManager;
@Before
public void setUp() throws Exception {
connectivityManager =
(ConnectivityManager)
- RuntimeEnvironment.application.getSystemService(Context.CONNECTIVITY_SERVICE);
- shadowConnectivityManager = shadowOf(connectivityManager);
+ getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
shadowOfActiveNetworkInfo = shadowOf(connectivityManager.getActiveNetworkInfo());
}
@@ -86,7 +89,7 @@ public class ShadowConnectivityManagerTest {
0,
true,
NetworkInfo.State.CONNECTED);
- shadowConnectivityManager.addNetwork(vpnNetwork, vpnNetworkInfo);
+ shadowOf(connectivityManager).addNetwork(vpnNetwork, vpnNetworkInfo);
NetworkInfo returnedNetworkInfo = connectivityManager.getNetworkInfo(vpnNetwork);
assertThat(returnedNetworkInfo).isSameAs(vpnNetworkInfo);
@@ -95,7 +98,7 @@ public class ShadowConnectivityManagerTest {
@Test @Config(minSdk = LOLLIPOP)
public void getNetworkInfo_shouldNotReturnRemovedNetwork() throws Exception {
Network wifiNetwork = ShadowNetwork.newInstance(ShadowConnectivityManager.NET_ID_WIFI);
- shadowConnectivityManager.removeNetwork(wifiNetwork);
+ shadowOf(connectivityManager).removeNetwork(wifiNetwork);
NetworkInfo returnedNetworkInfo = connectivityManager.getNetworkInfo(wifiNetwork);
assertThat(returnedNetworkInfo).isNull();
@@ -113,21 +116,22 @@ public class ShadowConnectivityManagerTest {
@Test
public void shouldGetAndSetBackgroundDataSetting() throws Exception {
assertThat(connectivityManager.getBackgroundDataSetting()).isFalse();
- shadowConnectivityManager.setBackgroundDataSetting(true);
+ shadowOf(connectivityManager).setBackgroundDataSetting(true);
assertThat(connectivityManager.getBackgroundDataSetting()).isTrue();
}
@Test
public void setActiveNetworkInfo_shouldSetActiveNetworkInfo() throws Exception {
- shadowConnectivityManager.setActiveNetworkInfo(null);
+ shadowOf(connectivityManager).setActiveNetworkInfo(null);
assertThat(connectivityManager.getActiveNetworkInfo()).isNull();
- shadowConnectivityManager.setActiveNetworkInfo(
- ShadowNetworkInfo.newInstance(
- null,
- ConnectivityManager.TYPE_MOBILE_HIPRI,
- TelephonyManager.NETWORK_TYPE_EDGE,
- true,
- NetworkInfo.State.DISCONNECTED));
+ shadowOf(connectivityManager)
+ .setActiveNetworkInfo(
+ ShadowNetworkInfo.newInstance(
+ null,
+ ConnectivityManager.TYPE_MOBILE_HIPRI,
+ TelephonyManager.NETWORK_TYPE_EDGE,
+ true,
+ NetworkInfo.State.DISCONNECTED));
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
@@ -146,22 +150,23 @@ public class ShadowConnectivityManagerTest {
@Test
@Config(minSdk = M)
public void getActiveNetwork_nullIfNetworkNotActive() {
- shadowConnectivityManager.setDefaultNetworkActive(false);
+ shadowOf(connectivityManager).setDefaultNetworkActive(false);
assertThat(connectivityManager.getActiveNetwork()).isNull();
}
@Test
@Config(minSdk = M)
public void setActiveNetworkInfo_shouldSetActiveNetwork() throws Exception {
- shadowConnectivityManager.setActiveNetworkInfo(null);
+ shadowOf(connectivityManager).setActiveNetworkInfo(null);
assertThat(connectivityManager.getActiveNetworkInfo()).isNull();
- shadowConnectivityManager.setActiveNetworkInfo(
- ShadowNetworkInfo.newInstance(
- null,
- ConnectivityManager.TYPE_MOBILE_HIPRI,
- TelephonyManager.NETWORK_TYPE_EDGE,
- true,
- NetworkInfo.State.DISCONNECTED));
+ shadowOf(connectivityManager)
+ .setActiveNetworkInfo(
+ ShadowNetworkInfo.newInstance(
+ null,
+ ConnectivityManager.TYPE_MOBILE_HIPRI,
+ TelephonyManager.NETWORK_TYPE_EDGE,
+ true,
+ NetworkInfo.State.DISCONNECTED));
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
@@ -178,7 +183,7 @@ public class ShadowConnectivityManagerTest {
assertThat(infos).asList().hasSize(2);
assertThat(infos).asList().contains(connectivityManager.getActiveNetworkInfo());
- shadowConnectivityManager.setActiveNetworkInfo(null);
+ shadowOf(connectivityManager).setActiveNetworkInfo(null);
assertThat(connectivityManager.getAllNetworkInfo()).isEmpty();
}
@@ -193,7 +198,7 @@ public class ShadowConnectivityManagerTest {
0 /* subType */,
true /* isAvailable */,
true /* isConnected */);
- shadowConnectivityManager.setActiveNetworkInfo(networkInfo);
+ shadowOf(connectivityManager).setActiveNetworkInfo(networkInfo);
// Verify that getAllNetworks and getAllNetworkInfo match.
Network[] networks = connectivityManager.getAllNetworks();
@@ -208,7 +213,7 @@ public class ShadowConnectivityManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void getAllNetworkInfo_nullIfNetworkNotActive() {
- shadowConnectivityManager.setDefaultNetworkActive(false);
+ shadowOf(connectivityManager).setDefaultNetworkActive(false);
assertThat(connectivityManager.getAllNetworkInfo()).isNull();
}
@@ -220,7 +225,7 @@ public class ShadowConnectivityManagerTest {
@Test @Config(minSdk = LOLLIPOP)
public void getAllNetworks_shouldReturnNoNetworksWhenCleared() throws Exception {
- shadowConnectivityManager.clearAllNetworks();
+ shadowOf(connectivityManager).clearAllNetworks();
Network[] networks = connectivityManager.getAllNetworks();
assertThat(networks).isEmpty();
}
@@ -228,7 +233,7 @@ public class ShadowConnectivityManagerTest {
@Test @Config(minSdk = LOLLIPOP)
public void getAllNetworks_shouldReturnAddedNetworks() throws Exception {
// Let's start clear.
- shadowConnectivityManager.clearAllNetworks();
+ shadowOf(connectivityManager).clearAllNetworks();
// Add a "VPN network".
Network vpnNetwork = ShadowNetwork.newInstance(123);
@@ -239,7 +244,7 @@ public class ShadowConnectivityManagerTest {
0,
true,
NetworkInfo.State.CONNECTED);
- shadowConnectivityManager.addNetwork(vpnNetwork, vpnNetworkInfo);
+ shadowOf(connectivityManager).addNetwork(vpnNetwork, vpnNetworkInfo);
Network[] networks = connectivityManager.getAllNetworks();
assertThat(networks).asList().hasSize(1);
@@ -254,7 +259,7 @@ public class ShadowConnectivityManagerTest {
@Test @Config(minSdk = LOLLIPOP)
public void getAllNetworks_shouldNotReturnRemovedNetworks() throws Exception {
Network wifiNetwork = ShadowNetwork.newInstance(ShadowConnectivityManager.NET_ID_WIFI);
- shadowConnectivityManager.removeNetwork(wifiNetwork);
+ shadowOf(connectivityManager).removeNetwork(wifiNetwork);
Network[] networks = connectivityManager.getAllNetworks();
assertThat(networks).asList().hasSize(1);
@@ -276,13 +281,13 @@ public class ShadowConnectivityManagerTest {
connectivityManager.reportNetworkConnectivity(wifiNetwork, true);
Map<Network, Boolean> reportedNetworks =
- shadowConnectivityManager.getReportedNetworkConnectivity();
+ shadowOf(connectivityManager).getReportedNetworkConnectivity();
assertThat(reportedNetworks.size()).isEqualTo(1);
assertThat(reportedNetworks.get(wifiNetwork)).isTrue();
// Update the status.
connectivityManager.reportNetworkConnectivity(wifiNetwork, false);
- reportedNetworks = shadowConnectivityManager.getReportedNetworkConnectivity();
+ reportedNetworks = shadowOf(connectivityManager).getReportedNetworkConnectivity();
assertThat(reportedNetworks.size()).isEqualTo(1);
assertThat(reportedNetworks.get(wifiNetwork)).isFalse();
}
@@ -297,7 +302,7 @@ public class ShadowConnectivityManagerTest {
@Test @Config(minSdk = LOLLIPOP)
public void getNetworkCallbacks_shouldHaveEmptyDefault() throws Exception {
- assertEquals(0, shadowConnectivityManager.getNetworkCallbacks().size());
+ assertThat(shadowOf(connectivityManager).getNetworkCallbacks()).isEmpty();
}
private static ConnectivityManager.NetworkCallback createSimpleCallback() {
@@ -315,7 +320,7 @@ public class ShadowConnectivityManagerTest {
NetworkRequest.Builder builder = new NetworkRequest.Builder();
ConnectivityManager.NetworkCallback callback = createSimpleCallback();
connectivityManager.requestNetwork(builder.build(), callback);
- assertThat(shadowConnectivityManager.getNetworkCallbacks()).hasSize(1);
+ assertThat(shadowOf(connectivityManager).getNetworkCallbacks()).hasSize(1);
}
@Test @Config(minSdk = LOLLIPOP)
@@ -323,7 +328,7 @@ public class ShadowConnectivityManagerTest {
NetworkRequest.Builder builder = new NetworkRequest.Builder();
ConnectivityManager.NetworkCallback callback = createSimpleCallback();
connectivityManager.registerNetworkCallback(builder.build(), callback);
- assertEquals(1, shadowConnectivityManager.getNetworkCallbacks().size());
+ assertThat(shadowOf(connectivityManager).getNetworkCallbacks()).hasSize(1);
}
@Test @Config(minSdk = LOLLIPOP)
@@ -335,11 +340,11 @@ public class ShadowConnectivityManagerTest {
connectivityManager.registerNetworkCallback(builder.build(), callback1);
connectivityManager.registerNetworkCallback(builder.build(), callback2);
// Remove one at the time.
- assertEquals(2, shadowConnectivityManager.getNetworkCallbacks().size());
+ assertThat(shadowOf(connectivityManager).getNetworkCallbacks()).hasSize(2);
connectivityManager.unregisterNetworkCallback(callback2);
- assertEquals(1, shadowConnectivityManager.getNetworkCallbacks().size());
+ assertThat(shadowOf(connectivityManager).getNetworkCallbacks()).hasSize(1);
connectivityManager.unregisterNetworkCallback(callback1);
- assertEquals(0, shadowConnectivityManager.getNetworkCallbacks().size());
+ assertThat(shadowOf(connectivityManager).getNetworkCallbacks()).isEmpty();
}
@Test(expected=IllegalArgumentException.class) @Config(minSdk = LOLLIPOP)
@@ -355,33 +360,33 @@ public class ShadowConnectivityManagerTest {
@Test
public void isActiveNetworkMetered_mobileIsMetered() {
- shadowConnectivityManager.setActiveNetworkInfo(
- connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE));
+ shadowOf(connectivityManager)
+ .setActiveNetworkInfo(connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE));
assertThat(connectivityManager.isActiveNetworkMetered()).isTrue();
}
@Test
public void isActiveNetworkMetered_nonMobileIsUnmetered() {
- shadowConnectivityManager.setActiveNetworkInfo(
- connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI));
+ shadowOf(connectivityManager)
+ .setActiveNetworkInfo(connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI));
assertThat(connectivityManager.isActiveNetworkMetered()).isFalse();
}
@Test
public void isActiveNetworkMetered_noActiveNetwork() {
- shadowConnectivityManager.setActiveNetworkInfo(null);
+ shadowOf(connectivityManager).setActiveNetworkInfo(null);
assertThat(connectivityManager.isActiveNetworkMetered()).isFalse();
}
@Test
public void isActiveNetworkMetered_noDefaultNetworkActive() {
- shadowConnectivityManager.setDefaultNetworkActive(false);
+ shadowOf(connectivityManager).setDefaultNetworkActive(false);
assertThat(connectivityManager.isActiveNetworkMetered()).isFalse();
}
@Test
@Config(minSdk = M)
- public void bindProcessToNetwork_should() {
+ public void bindProcessToNetwork_shouldGetBoundNetworkForProcess() {
Network network = ShadowNetwork.newInstance(789);
connectivityManager.bindProcessToNetwork(network);
assertThat(connectivityManager.getBoundNetworkForProcess()).isSameAs(network);
@@ -390,14 +395,14 @@ public class ShadowConnectivityManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void isDefaultNetworkActive_defaultActive() {
- assertThat(shadowConnectivityManager.isDefaultNetworkActive()).isTrue();
+ assertThat(shadowOf(connectivityManager).isDefaultNetworkActive()).isTrue();
}
@Test
@Config(minSdk = LOLLIPOP)
public void isDefaultNetworkActive_notActive() {
- shadowConnectivityManager.setDefaultNetworkActive(false);
- assertThat(shadowConnectivityManager.isDefaultNetworkActive()).isFalse();
+ shadowOf(connectivityManager).setDefaultNetworkActive(false);
+ assertThat(shadowOf(connectivityManager).isDefaultNetworkActive()).isFalse();
}
private static ConnectivityManager.OnNetworkActiveListener createSimpleOnNetworkActiveListener() {
@@ -417,7 +422,7 @@ public class ShadowConnectivityManagerTest {
connectivityManager.addDefaultNetworkActiveListener(listener1);
connectivityManager.addDefaultNetworkActiveListener(listener2);
- shadowConnectivityManager.setDefaultNetworkActive(true);
+ shadowOf(connectivityManager).setDefaultNetworkActive(true);
verify(listener1).onNetworkActive();
verify(listener2).onNetworkActive();
@@ -434,21 +439,21 @@ public class ShadowConnectivityManagerTest {
connectivityManager.addDefaultNetworkActiveListener(listener1);
connectivityManager.addDefaultNetworkActiveListener(listener2);
- shadowConnectivityManager.setDefaultNetworkActive(true);
+ shadowOf(connectivityManager).setDefaultNetworkActive(true);
verify(listener1).onNetworkActive();
verify(listener2).onNetworkActive();
// Remove one at the time.
connectivityManager.removeDefaultNetworkActiveListener(listener2);
- shadowConnectivityManager.setDefaultNetworkActive(true);
+ shadowOf(connectivityManager).setDefaultNetworkActive(true);
verify(listener1, times(2)).onNetworkActive();
verify(listener2).onNetworkActive();
connectivityManager.removeDefaultNetworkActiveListener(listener1);
- shadowConnectivityManager.setDefaultNetworkActive(true);
+ shadowOf(connectivityManager).setDefaultNetworkActive(true);
verify(listener1, times(2)).onNetworkActive();
verify(listener2).onNetworkActive();
@@ -460,5 +465,50 @@ public class ShadowConnectivityManagerTest {
// Verify that exception is thrown.
connectivityManager.removeDefaultNetworkActiveListener(null);
}
-}
+ @Test
+ @Config(minSdk = LOLLIPOP)
+ public void getNetworkCapabilities() throws Exception {
+ NetworkCapabilities nc = new NetworkCapabilities(null);
+ ReflectionHelpers.callInstanceMethod(
+ nc,
+ "addCapability",
+ ClassParameter.from(int.class, NetworkCapabilities.NET_CAPABILITY_MMS));
+
+ shadowOf(connectivityManager).setNetworkCapabilities(
+ shadowOf(connectivityManager).getActiveNetwork(), nc);
+
+ assertThat(
+ shadowOf(connectivityManager)
+ .getNetworkCapabilities(shadowOf(connectivityManager).getActiveNetwork())
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS))
+ .isTrue();
+ }
+
+ @Test
+ @Config(minSdk = N)
+ public void getCaptivePortalServerUrl_shouldReturnAddedUrl() {
+ assertThat(connectivityManager.getCaptivePortalServerUrl()).isEqualTo("http://10.0.0.2");
+
+ shadowOf(connectivityManager).setCaptivePortalServerUrl("http://10.0.0.1");
+ assertThat(connectivityManager.getCaptivePortalServerUrl()).isEqualTo("http://10.0.0.1");
+
+ shadowOf(connectivityManager).setCaptivePortalServerUrl("http://10.0.0.2");
+ assertThat(connectivityManager.getCaptivePortalServerUrl()).isEqualTo("http://10.0.0.2");
+ }
+
+ @Test
+ @Config(minSdk = KITKAT)
+ public void setAirplaneMode() {
+ connectivityManager.setAirplaneMode(false);
+ assertThat(
+ Settings.Global.getInt(
+ getApplicationContext().getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, -1))
+ .isEqualTo(0);
+ connectivityManager.setAirplaneMode(true);
+ assertThat(
+ Settings.Global.getInt(
+ getApplicationContext().getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, -1))
+ .isEqualTo(1);
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentObserverTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentObserverTest.java
index 7e464512f..f51c7c827 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentObserverTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentObserverTest.java
@@ -5,12 +5,12 @@ import static com.google.common.truth.Truth.assertThat;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
+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 ShadowContentObserverTest {
private TestContentObserver observer;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderClientTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderClientTest.java
index 622f0e1fd..47a94b905 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderClientTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderClientTest.java
@@ -7,6 +7,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.ContentProvider;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
@@ -15,16 +16,16 @@ import android.content.ContentValues;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
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;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowContentProviderClientTest {
private static final String AUTHORITY = "org.robolectric";
@@ -37,7 +38,8 @@ public class ShadowContentProviderClientTest {
private static final String MIME_TYPE = "application/octet-stream";
@Mock ContentProvider provider;
- ContentResolver contentResolver = RuntimeEnvironment.application.getContentResolver();
+ ContentResolver contentResolver =
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver();
@Before
public void setUp() {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderOperationBuilderTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderOperationBuilderTest.java
index a7c3137ee..32175b400 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderOperationBuilderTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderOperationBuilderTest.java
@@ -8,11 +8,11 @@ import android.content.ContentProviderOperation.Builder;
import android.content.ContentValues;
import android.database.Cursor;
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 ShadowContentProviderOperationBuilderTest {
private Builder builder;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderOperationTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderOperationTest.java
index b2f39c813..bb8e1157e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderOperationTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderOperationTest.java
@@ -4,16 +4,14 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.ContentProviderOperation;
import android.net.Uri;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Collections;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
-/**
- * Tests for {@link ShadowContentProviderOperation}.
- */
-@RunWith(RobolectricTestRunner.class)
+/** Tests for {@link ShadowContentProviderOperation}. */
+@RunWith(AndroidJUnit4.class)
public class ShadowContentProviderOperationTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderResultTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderResultTest.java
index 4ab8bc715..40a47b993 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderResultTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderResultTest.java
@@ -4,11 +4,11 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.ContentProviderResult;
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 ShadowContentProviderResultTest {
@Test
public void count() {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderTest.java
index 87d7f575f..fd3869501 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentProviderTest.java
@@ -5,13 +5,13 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.content.ContentProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.testing.TestContentProvider1;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowContentProviderTest {
@Config(minSdk = KITKAT)
@Test public void testSetCallingPackage() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentResolverTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentResolverTest.java
index 6a947dcf8..5d0d8db2d 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentResolverTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentResolverTest.java
@@ -35,6 +35,8 @@ import android.os.CancellationSignal;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileDescriptor;
@@ -50,12 +52,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.fakes.BaseCursor;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowContentResolverTest {
private static final String AUTHORITY = "org.robolectric";
@@ -67,7 +68,8 @@ public class ShadowContentResolverTest {
@Before
public void setUp() {
- contentResolver = RuntimeEnvironment.application.getContentResolver();
+ contentResolver =
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver();
shadowContentResolver = shadowOf(contentResolver);
uri21 = Uri.parse(EXTERNAL_CONTENT_URI.toString() + "/21");
uri22 = Uri.parse(EXTERNAL_CONTENT_URI.toString() + "/22");
@@ -286,11 +288,13 @@ public class ShadowContentResolverTest {
ProviderInfo providerInfo0 = new ProviderInfo();
providerInfo0.authority = "the-authority"; // todo: support multiple authorities
providerInfo0.grantUriPermissions = true;
- mock.attachInfo(RuntimeEnvironment.application, providerInfo0);
+ mock.attachInfo((Application) ApplicationProvider.getApplicationContext(), providerInfo0);
mock.onCreate();
ArgumentCaptor<ProviderInfo> captor = ArgumentCaptor.forClass(ProviderInfo.class);
- verify(mock).attachInfo(same(RuntimeEnvironment.application), captor.capture());
+ verify(mock)
+ .attachInfo(
+ same((Application) ApplicationProvider.getApplicationContext()), captor.capture());
ProviderInfo providerInfo = captor.getValue();
assertThat(providerInfo.authority).isEqualTo("the-authority");
@@ -674,7 +678,7 @@ public class ShadowContentResolverTest {
contentResolver.notifyChange(EXTERNAL_CONTENT_URI, null);
assertThat(co.changed).isTrue();
- scr.clearContentObservers();
+ contentResolver.unregisterContentObserver(co);
assertThat(scr.getContentObservers(EXTERNAL_CONTENT_URI)).isEmpty();
}
@@ -874,7 +878,10 @@ public class ShadowContentResolverTest {
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
- final File file = new File(RuntimeEnvironment.application.getFilesDir(), "test_file");
+ final File file =
+ new File(
+ ((Application) ApplicationProvider.getApplicationContext()).getFilesDir(),
+ "test_file");
try {
file.createNewFile();
} catch (IOException e) {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentUrisTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentUrisTest.java
index 92fbbb1fd..99f3c045b 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentUrisTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentUrisTest.java
@@ -4,12 +4,12 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.ContentUris;
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;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowContentUrisTest {
Uri URI;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentValuesTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentValuesTest.java
index d4e1dfb09..7e2e5cdce 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContentValuesTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContentValuesTest.java
@@ -3,12 +3,12 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.content.ContentValues;
+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 ShadowContentValuesTest {
private static final String KEY = "key";
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContextImplTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContextImplTest.java
index 230edf48e..6c276d10b 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContextImplTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContextImplTest.java
@@ -7,6 +7,7 @@ import static android.os.Build.VERSION_CODES.N;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.PendingIntent;
import android.app.WallpaperManager;
import android.bluetooth.BluetoothManager;
@@ -21,18 +22,18 @@ import android.os.Process;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
import android.widget.RemoteViews;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowContextImplTest {
- private final ContextWrapper context = RuntimeEnvironment.application;
+ private final ContextWrapper context = (Application) ApplicationProvider.getApplicationContext();
private final ShadowContextImpl shadowContext = Shadow.extract(context.getBaseContext());
@Test
@@ -57,13 +58,13 @@ public class ShadowContextImplTest {
public void testMoveSharedPreferencesFrom() throws Exception {
String PREFS = "PREFS";
String PREF_NAME = "TOKEN_PREF";
- RuntimeEnvironment.application
+ ((Application) ApplicationProvider.getApplicationContext())
.getSharedPreferences(PREFS, Context.MODE_PRIVATE)
.edit()
.putString(PREF_NAME, "token")
.commit();
- Context context = RuntimeEnvironment.application;
+ Context context = (Application) ApplicationProvider.getApplicationContext();
Context dpContext = context.createDeviceProtectedStorageContext();
assertThat(dpContext.getSharedPreferences(PREFS, Context.MODE_PRIVATE).contains(PREF_NAME))
@@ -115,14 +116,15 @@ public class ShadowContextImplTest {
context,
0,
new Intent()
- .setClassName(RuntimeEnvironment.application, "ActivityIntent")
+ .setClassName(
+ (Application) ApplicationProvider.getApplicationContext(), "ActivityIntent")
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
PendingIntent.FLAG_UPDATE_CURRENT);
context.startIntentSender(intent.getIntentSender(), null, 0, 0, 0);
assertThat(
- shadowOf(RuntimeEnvironment.application)
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
.getNextStartedActivity()
.getComponent()
.getClassName())
@@ -135,13 +137,15 @@ public class ShadowContextImplTest {
PendingIntent.getBroadcast(
context,
0,
- new Intent().setClassName(RuntimeEnvironment.application, "BroadcastIntent"),
+ new Intent()
+ .setClassName(
+ (Application) ApplicationProvider.getApplicationContext(), "BroadcastIntent"),
PendingIntent.FLAG_UPDATE_CURRENT);
context.startIntentSender(intent.getIntentSender(), null, 0, 0, 0);
assertThat(
- shadowOf(RuntimeEnvironment.application)
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
.getBroadcastIntents()
.get(0)
.getComponent()
@@ -155,13 +159,15 @@ public class ShadowContextImplTest {
PendingIntent.getService(
context,
0,
- new Intent().setClassName(RuntimeEnvironment.application, "ServiceIntent"),
+ new Intent()
+ .setClassName(
+ (Application) ApplicationProvider.getApplicationContext(), "ServiceIntent"),
PendingIntent.FLAG_UPDATE_CURRENT);
context.startIntentSender(intent.getIntentSender(), null, 0, 0, 0);
assertThat(
- shadowOf(RuntimeEnvironment.application)
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
.getNextStartedService()
.getComponent()
.getClassName())
@@ -171,22 +177,30 @@ public class ShadowContextImplTest {
@Test
public void createPackageContext() throws Exception {
Context packageContext =
- context.createPackageContext(RuntimeEnvironment.application.getPackageName(), 0);
+ context.createPackageContext(
+ ((Application) ApplicationProvider.getApplicationContext()).getPackageName(), 0);
LayoutInflater inflater =
(LayoutInflater)
- RuntimeEnvironment.application.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.cloneInContext(packageContext);
- inflater.inflate(R.layout.remote_views, new FrameLayout(RuntimeEnvironment.application), false);
+ inflater.inflate(
+ R.layout.remote_views,
+ new FrameLayout((Application) ApplicationProvider.getApplicationContext()),
+ false);
}
@Test
public void createPackageContextRemoteViews() throws Exception {
RemoteViews remoteViews =
- new RemoteViews(RuntimeEnvironment.application.getPackageName(), R.layout.remote_views);
+ new RemoteViews(
+ ((Application) ApplicationProvider.getApplicationContext()).getPackageName(),
+ R.layout.remote_views);
remoteViews.apply(
- RuntimeEnvironment.application, new FrameLayout(RuntimeEnvironment.application));
+ (Application) ApplicationProvider.getApplicationContext(),
+ new FrameLayout((Application) ApplicationProvider.getApplicationContext()));
}
@Test
@@ -201,7 +215,10 @@ public class ShadowContextImplTest {
serviceIntent, serviceConnection, flags, Process.myUserHandle()))
.isTrue();
- assertThat(shadowOf(RuntimeEnvironment.application).getBoundServiceConnections()).hasSize(1);
+ assertThat(
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .getBoundServiceConnections())
+ .hasSize(1);
}
@Test
@@ -212,7 +229,10 @@ public class ShadowContextImplTest {
assertThat(context.bindService(serviceIntent, serviceConnection, flags)).isTrue();
- assertThat(shadowOf(RuntimeEnvironment.application).getBoundServiceConnections()).hasSize(1);
+ assertThat(
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .getBoundServiceConnections())
+ .hasSize(1);
}
@Test
@@ -221,7 +241,8 @@ public class ShadowContextImplTest {
Intent serviceIntent = new Intent(action);
ServiceConnection serviceConnection = buildServiceConnection();
int flags = 0;
- shadowOf(RuntimeEnvironment.application).declareActionUnbindable(action);
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .declareActionUnbindable(action);
assertThat(context.bindService(serviceIntent, serviceConnection, flags)).isFalse();
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContextTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContextTest.java
index 897ceccde..15c8ce552 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContextTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContextTest.java
@@ -4,12 +4,15 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
+import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.os.Build.VERSION_CODES;
import android.util.AttributeSet;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -20,13 +23,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowContextTest {
- private final Context context = RuntimeEnvironment.application;
+ private final Context context = (Application) ApplicationProvider.getApplicationContext();
@Test
@Config(minSdk = JELLY_BEAN_MR1)
@@ -43,7 +44,7 @@ public class ShadowContextTest {
@Config(minSdk = VERSION_CODES.O)
public void startForegroundService() {
Intent intent = new Intent();
- RuntimeEnvironment.application.startForegroundService(intent);
+ ((Application) ApplicationProvider.getApplicationContext()).startForegroundService(intent);
assertThat(ShadowApplication.getInstance().getNextStartedService()).isEqualTo(intent);
}
@@ -88,7 +89,7 @@ public class ShadowContextTest {
File cacheTest = new File(context.getCacheDir(), "__test__");
assertThat(cacheTest.getAbsolutePath())
- .startsWith(System.getProperty("java.io.tmpdir"));
+ .startsWith(System.getProperty("java.io.tmpdir"));
assertThat(cacheTest.getAbsolutePath())
.endsWith(File.separator + "__test__");
@@ -104,9 +105,9 @@ public class ShadowContextTest {
File cacheTest = new File(context.getExternalCacheDir(), "__test__");
assertThat(cacheTest.getAbsolutePath())
- .startsWith(System.getProperty("java.io.tmpdir"));
+ .startsWith(System.getProperty("java.io.tmpdir"));
assertThat(cacheTest.getAbsolutePath())
- .endsWith(File.separator + "__test__");
+ .endsWith(File.separator + "__test__");
try (FileOutputStream fos = new FileOutputStream(cacheTest)) {
fos.write("test".getBytes(UTF_8));
@@ -139,15 +140,15 @@ public class ShadowContextTest {
@Test
public void getDatabasePath_shouldAllowAbsolutePaths() throws Exception {
- String testDbName;
-
- if (System.getProperty("os.name").startsWith("Windows")) {
- testDbName = "C:\\absolute\\full\\path\\to\\db\\abc.db";
- } else {
- testDbName = "/absolute/full/path/to/db/abc.db";
- }
- File dbFile = context.getDatabasePath(testDbName);
- assertThat(dbFile).isEqualTo(new File(testDbName));
+ String testDbName;
+
+ if (System.getProperty("os.name").startsWith("Windows")) {
+ testDbName = "C:\\absolute\\full\\path\\to\\db\\abc.db";
+ } else {
+ testDbName = "/absolute/full/path/to/db/abc.db";
+ }
+ File dbFile = context.getDatabasePath(testDbName);
+ assertThat(dbFile).isEqualTo(new File(testDbName));
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContextWrapperTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContextWrapperTest.java
index 7c33a71d1..ef485e173 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContextWrapperTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContextWrapperTest.java
@@ -10,6 +10,7 @@ import static org.robolectric.Robolectric.buildActivity;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
+import android.app.Application;
import android.appwidget.AppWidgetProvider;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -24,6 +25,8 @@ import android.os.HandlerThread;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.util.concurrent.SettableFuture;
import java.util.ArrayList;
import java.util.List;
@@ -33,16 +36,14 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowContextWrapperTest {
public ArrayList<String> transcript;
private ContextWrapper contextWrapper;
- private final Context context = RuntimeEnvironment.application;
+ private final Context context = (Application) ApplicationProvider.getApplicationContext();
private final ShadowContextWrapper shadowContextWrapper = Shadow.extract(context);
@Before public void setUp() throws Exception {
@@ -263,12 +264,15 @@ public class ShadowContextWrapperTest {
public void broadcastReceivers_shouldBeSharedAcrossContextsPerApplicationContext() throws Exception {
BroadcastReceiver receiver = broadcastReceiver("Larry");
- new ContextWrapper(RuntimeEnvironment.application).registerReceiver(receiver, intentFilter("foo", "baz"));
- new ContextWrapper(RuntimeEnvironment.application).sendBroadcast(new Intent("foo"));
- RuntimeEnvironment.application.sendBroadcast(new Intent("baz"));
+ new ContextWrapper((Application) ApplicationProvider.getApplicationContext())
+ .registerReceiver(receiver, intentFilter("foo", "baz"));
+ new ContextWrapper((Application) ApplicationProvider.getApplicationContext())
+ .sendBroadcast(new Intent("foo"));
+ ((Application) ApplicationProvider.getApplicationContext()).sendBroadcast(new Intent("baz"));
assertThat(transcript).containsExactly("Larry notified of foo", "Larry notified of baz");
- new ContextWrapper(RuntimeEnvironment.application).unregisterReceiver(receiver);
+ new ContextWrapper((Application) ApplicationProvider.getApplicationContext())
+ .unregisterReceiver(receiver);
}
@Test
@@ -343,9 +347,12 @@ public class ShadowContextWrapperTest {
@Test
public void shouldReturnApplicationContext_forViewContextInflatedWithApplicationContext() throws Exception {
- View view = LayoutInflater.from(RuntimeEnvironment.application).inflate(R.layout.custom_layout, null);
+ View view =
+ LayoutInflater.from((Application) ApplicationProvider.getApplicationContext())
+ .inflate(R.layout.custom_layout, null);
Context viewContext = new ContextWrapper(view.getContext());
- assertThat(viewContext.getApplicationContext()).isEqualTo(RuntimeEnvironment.application);
+ assertThat(viewContext.getApplicationContext())
+ .isEqualTo((Application) ApplicationProvider.getApplicationContext());
}
@Test
@@ -389,7 +396,11 @@ public class ShadowContextWrapperTest {
@Test
public void bindServiceDelegatesToShadowApplication() {
contextWrapper.bindService(new Intent("foo"), new TestService(), Context.BIND_AUTO_CREATE);
- assertEquals("foo", shadowOf(RuntimeEnvironment.application).getNextStartedService().getAction());
+ assertEquals(
+ "foo",
+ shadowOf((Application) ApplicationProvider.getApplicationContext())
+ .getNextStartedService()
+ .getAction());
}
@Test
@@ -430,7 +441,8 @@ public class ShadowContextWrapperTest {
@Test
public void packageManagerShouldNotBeNullWhenWrappingAnApplication() {
- assertThat(RuntimeEnvironment.application.getPackageManager()).isNotNull();
+ assertThat(((Application) ApplicationProvider.getApplicationContext()).getPackageManager())
+ .isNotNull();
}
@Test
@@ -487,7 +499,7 @@ public class ShadowContextWrapperTest {
@Test
public void sendBroadcast_shouldOnlySendIntentWithTypeWhenReceiverMatchesType()
- throws IntentFilter.MalformedMimeTypeException {
+ throws IntentFilter.MalformedMimeTypeException {
final BroadcastReceiver viewAllTypesReceiver = broadcastReceiver("ViewActionWithAnyTypeReceiver");
final IntentFilter allTypesIntentFilter = intentFilter("view");
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCookieManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCookieManagerTest.java
index 1b03ede58..79fb9b480 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCookieManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCookieManagerTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.webkit.CookieManager;
+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 ShadowCookieManagerTest {
private final String url = "robolectric.org/";
private final String httpUrl = "http://robolectric.org/";
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCookieSyncManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCookieSyncManagerTest.java
index 83ba8bcd8..3beee3c15 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCookieSyncManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCookieSyncManagerTest.java
@@ -4,11 +4,11 @@ import static com.google.common.truth.Truth.assertThat;
import android.app.Activity;
import android.webkit.CookieSyncManager;
+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 ShadowCookieSyncManagerTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCornerPathEffectTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCornerPathEffectTest.java
index 5f1717ca7..9df505fa7 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCornerPathEffectTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCornerPathEffectTest.java
@@ -4,11 +4,11 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.graphics.CornerPathEffect;
+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 ShadowCornerPathEffectTest {
@Test
public void shouldGetRadius() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCountDownTimerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCountDownTimerTest.java
index 166ff66a8..1238b396c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCountDownTimerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCountDownTimerTest.java
@@ -3,13 +3,13 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.os.CountDownTimer;
+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.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowCountDownTimerTest {
private ShadowCountDownTimer shadowCountDownTimer;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCountingAdapter.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCountingAdapter.java
index c4be209c3..249f36df3 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCountingAdapter.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCountingAdapter.java
@@ -1,10 +1,11 @@
package org.robolectric.shadows;
+import android.app.Application;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
-import org.robolectric.RuntimeEnvironment;
+import androidx.test.core.app.ApplicationProvider;
class ShadowCountingAdapter extends BaseAdapter {
private int itemCount;
@@ -35,7 +36,7 @@ class ShadowCountingAdapter extends BaseAdapter {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- TextView textView = new TextView(RuntimeEnvironment.application);
+ TextView textView = new TextView((Application) ApplicationProvider.getApplicationContext());
textView.setText("Item " + position);
return textView;
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCursorAdapterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCursorAdapterTest.java
index 56d59266b..8480ddb7d 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCursorAdapterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCursorAdapterTest.java
@@ -2,19 +2,20 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
+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 ShadowCursorAdapterTest {
private Cursor curs;
@@ -89,7 +90,7 @@ public class ShadowCursorAdapterTest {
private static class TestAdapter extends CursorAdapter {
public TestAdapter(Cursor curs) {
- super(RuntimeEnvironment.application, curs, false);
+ super((Application) ApplicationProvider.getApplicationContext(), curs, false);
}
@Override
@@ -104,7 +105,7 @@ public class ShadowCursorAdapterTest {
private static class TestAdapterWithFlags extends CursorAdapter {
public TestAdapterWithFlags(Cursor c, int flags) {
- super(RuntimeEnvironment.application, c, flags);
+ super((Application) ApplicationProvider.getApplicationContext(), c, flags);
}
@Override public View newView(Context context, Cursor cursor, ViewGroup parent) {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCursorWindowTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCursorWindowTest.java
index 6fa73237b..5c24fa4dd 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCursorWindowTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCursorWindowTest.java
@@ -5,11 +5,11 @@ import static com.google.common.truth.Truth.assertThat;
import android.database.CursorWindow;
import android.database.DatabaseUtils;
import android.database.MatrixCursor;
+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 ShadowCursorWindowTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowCursorWrapperTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowCursorWrapperTest.java
index 29abc453f..786b35dd0 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowCursorWrapperTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowCursorWrapperTest.java
@@ -13,15 +13,15 @@ import android.database.CursorWrapper;
import android.database.DataSetObserver;
import android.net.Uri;
import android.os.Bundle;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.lang.reflect.Method;
import java.util.HashMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowCursorWrapperTest {
private static class ForwardVerifier {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDatabaseUtilsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDatabaseUtilsTest.java
index b632ba015..f19a7f8ce 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDatabaseUtilsTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDatabaseUtilsTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.database.DatabaseUtils;
+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 ShadowDatabaseUtilsTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDateFormatTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDateFormatTest.java
index 4a58d2e78..1e780d9f5 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDateFormatTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDateFormatTest.java
@@ -3,13 +3,13 @@ package org.robolectric.shadows;
import static org.junit.Assert.assertEquals;
import android.text.format.DateFormat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Calendar;
import java.util.Date;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowDateFormatTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDateIntervalFormatTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDateIntervalFormatTest.java
index 157f60bb5..bde0e7263 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDateIntervalFormatTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDateIntervalFormatTest.java
@@ -8,16 +8,16 @@ import android.icu.text.SimpleDateFormat;
import android.icu.util.TimeZone;
import android.icu.util.ULocale;
import android.text.format.DateUtils;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import libcore.icu.DateIntervalFormat;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = M)
public class ShadowDateIntervalFormatTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDatePickerDialogTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDatePickerDialogTest.java
index 10f7029a5..0ef7a9be0 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDatePickerDialogTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDatePickerDialogTest.java
@@ -3,21 +3,24 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.DatePickerDialog;
import android.widget.DatePicker;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Locale;
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 ShadowDatePickerDialogTest {
@Test
public void returnsTheInitialYearMonthAndDayPassedIntoTheDatePickerDialog() throws Exception {
Locale.setDefault(Locale.US);
- DatePickerDialog datePickerDialog = new DatePickerDialog(RuntimeEnvironment.application, null, 2012, 6, 7);
+ DatePickerDialog datePickerDialog =
+ new DatePickerDialog(
+ (Application) ApplicationProvider.getApplicationContext(), null, 2012, 6, 7);
assertThat(shadowOf(datePickerDialog).getYear()).isEqualTo(2012);
assertThat(shadowOf(datePickerDialog).getMonthOfYear()).isEqualTo(6);
assertThat(shadowOf(datePickerDialog).getDayOfMonth()).isEqualTo(7);
@@ -32,7 +35,13 @@ public class ShadowDatePickerDialogTest {
}
};
- DatePickerDialog datePickerDialog = new DatePickerDialog(RuntimeEnvironment.application, expectedDateSetListener, 2012, 6, 7);
+ DatePickerDialog datePickerDialog =
+ new DatePickerDialog(
+ (Application) ApplicationProvider.getApplicationContext(),
+ expectedDateSetListener,
+ 2012,
+ 6,
+ 7);
ShadowDatePickerDialog shadowDatePickerDialog = shadowOf(datePickerDialog);
assertThat(shadowDatePickerDialog.getOnDateSetListenerCallback()).isEqualTo(expectedDateSetListener);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDateUtilsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDateUtilsTest.java
index db5adc5cc..f07fab63e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDateUtilsTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDateUtilsTest.java
@@ -6,16 +6,17 @@ import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
import static android.os.Build.VERSION_CODES.M;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.text.format.DateUtils;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Calendar;
import java.util.TimeZone;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowDateUtilsTest {
@Test
@@ -23,7 +24,11 @@ public class ShadowDateUtilsTest {
public void formatDateTime_withCurrentYear_worksSinceKitKat() {
final long millisAtStartOfYear = getMillisAtStartOfYear();
- String actual = DateUtils.formatDateTime(RuntimeEnvironment.application, millisAtStartOfYear, DateUtils.FORMAT_NUMERIC_DATE);
+ String actual =
+ DateUtils.formatDateTime(
+ (Application) ApplicationProvider.getApplicationContext(),
+ millisAtStartOfYear,
+ DateUtils.FORMAT_NUMERIC_DATE);
assertThat(actual).isEqualTo("1/1");
}
@@ -32,8 +37,13 @@ public class ShadowDateUtilsTest {
public void formatDateTime_withCurrentYear_worksSinceM() {
final long millisAtStartOfYear = getMillisAtStartOfYear();
- // starting with M, sometimes the year is there, sometimes it's missing, unless you specify FORMAT_SHOW_YEAR
- String actual = DateUtils.formatDateTime(RuntimeEnvironment.application, millisAtStartOfYear, DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_NUMERIC_DATE);
+ // starting with M, sometimes the year is there, sometimes it's missing, unless you specify
+ // FORMAT_SHOW_YEAR
+ String actual =
+ DateUtils.formatDateTime(
+ (Application) ApplicationProvider.getApplicationContext(),
+ millisAtStartOfYear,
+ DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_NUMERIC_DATE);
final int currentYear = Calendar.getInstance().get(Calendar.YEAR);
assertThat(actual).isEqualTo("1/1/" + currentYear);
}
@@ -45,14 +55,22 @@ public class ShadowDateUtilsTest {
final int currentYear = calendar.get(Calendar.YEAR);
final long millisAtStartOfYear = getMillisAtStartOfYear();
- String actual = DateUtils.formatDateTime(RuntimeEnvironment.application, millisAtStartOfYear, DateUtils.FORMAT_NUMERIC_DATE);
+ String actual =
+ DateUtils.formatDateTime(
+ (Application) ApplicationProvider.getApplicationContext(),
+ millisAtStartOfYear,
+ DateUtils.FORMAT_NUMERIC_DATE);
assertThat(actual).isEqualTo("1/1/" + currentYear);
}
@Test
public void formatDateTime_withPastYear() {
- String actual = DateUtils.formatDateTime(RuntimeEnvironment.application, 1420099200000L, DateUtils.FORMAT_NUMERIC_DATE);
- assertThat(actual).isEqualTo("1/1/2015");
+ String actual =
+ DateUtils.formatDateTime(
+ (Application) ApplicationProvider.getApplicationContext(),
+ 1420099200000L,
+ DateUtils.FORMAT_NUMERIC_DATE);
+ assertThat(actual).isEqualTo("1/1/2015");
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDebugTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDebugTest.java
index 9613cae39..9abcd68b1 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDebugTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDebugTest.java
@@ -5,15 +5,16 @@ import static android.os.Build.VERSION_CODES.M;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
+import android.app.Application;
import android.os.Debug;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowDebugTest {
private static final String TRACE_FILENAME = "dmtrace.trace";
@@ -35,8 +36,11 @@ public class ShadowDebugTest {
Debug.stopMethodTracing();
assertThat(
- new File(RuntimeEnvironment.application.getExternalFilesDir(null), TRACE_FILENAME)
- .exists())
+ new File(
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getExternalFilesDir(null),
+ TRACE_FILENAME)
+ .exists())
.isTrue();
}
@@ -47,8 +51,11 @@ public class ShadowDebugTest {
Debug.stopMethodTracing();
assertThat(
- new File(RuntimeEnvironment.application.getExternalFilesDir(null), TRACE_FILENAME)
- .exists())
+ new File(
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getExternalFilesDir(null),
+ TRACE_FILENAME)
+ .exists())
.isTrue();
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDevicePolicyManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDevicePolicyManagerTest.java
index 5757faf2c..11ab65bdb 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDevicePolicyManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDevicePolicyManagerTest.java
@@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
@@ -25,18 +26,18 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.os.UserManager;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/** Unit tests for {@link ShadowDevicePolicyManager}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public final class ShadowDevicePolicyManagerTest {
private DevicePolicyManager devicePolicyManager;
@@ -48,14 +49,18 @@ public final class ShadowDevicePolicyManagerTest {
public void setUp() {
devicePolicyManager =
(DevicePolicyManager)
- RuntimeEnvironment.application.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.DEVICE_POLICY_SERVICE);
userManager =
- (UserManager) RuntimeEnvironment.application.getSystemService(Context.USER_SERVICE);
+ (UserManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.USER_SERVICE);
testComponent = new ComponentName("com.example.app", "DeviceAdminReceiver");
- packageManager = RuntimeEnvironment.application.getPackageManager();
+ packageManager =
+ ((Application) ApplicationProvider.getApplicationContext()).getPackageManager();
}
@Test
@@ -576,7 +581,8 @@ public final class ShadowDevicePolicyManagerTest {
devicePolicyManager.setOrganizationName(testComponent, organizationName);
// THEN the name should be set properly
- assertThat(devicePolicyManager.getOrganizationName(testComponent)).isEqualTo(organizationName);
+ assertThat(devicePolicyManager.getOrganizationName(testComponent).toString())
+ .isEqualTo(organizationName);
}
@Test
@@ -623,7 +629,8 @@ public final class ShadowDevicePolicyManagerTest {
devicePolicyManager.setOrganizationName(testComponent, organizationName);
// THEN the name should be set properly
- assertThat(devicePolicyManager.getOrganizationName(testComponent)).isEqualTo(organizationName);
+ assertThat(devicePolicyManager.getOrganizationName(testComponent).toString())
+ .isEqualTo(organizationName);
}
@Test
@@ -958,4 +965,16 @@ public final class ShadowDevicePolicyManagerTest {
shadowOf(devicePolicyManager).setUserProvisioningState(STATE_USER_UNMANAGED);
assertThat(devicePolicyManager.getUserProvisioningState()).isEqualTo(STATE_USER_UNMANAGED);
}
+
+ @Test
+ @Config(minSdk = LOLLIPOP)
+ public void getProfileOwnerNameAsUser() {
+ int userId = 0;
+ String orgName = "organization";
+ assertThat(devicePolicyManager.getProfileOwnerNameAsUser(userId)).isNull();
+
+ shadowOf(devicePolicyManager).setProfileOwnerName(userId, orgName);
+
+ assertThat(devicePolicyManager.getProfileOwnerNameAsUser(userId)).isEqualTo(orgName);
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDialogPreferenceTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDialogPreferenceTest.java
index cc10a6bcf..cd4a4fd8a 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDialogPreferenceTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDialogPreferenceTest.java
@@ -6,13 +6,13 @@ import android.os.Bundle;
import android.preference.DialogPreference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowDialogPreferenceTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDialogTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDialogTest.java
index 2629a524f..9ca224a6d 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDialogTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDialogTest.java
@@ -9,28 +9,29 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowDialogTest {
@Test
public void shouldCallOnDismissListener() throws Exception {
final List<String> transcript = new ArrayList<>();
- final Dialog dialog = new Dialog(RuntimeEnvironment.application);
+ final Dialog dialog = new Dialog((Application) ApplicationProvider.getApplicationContext());
dialog.show();
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
@@ -48,7 +49,7 @@ public class ShadowDialogTest {
@Test
public void setContentViewWithViewAllowsFindById() throws Exception {
final int viewId = 1234;
- Context context = RuntimeEnvironment.application;
+ Context context = (Application) ApplicationProvider.getApplicationContext();
final Dialog dialog = new Dialog(context);
final View view = new View(context);
view.setId(viewId);
@@ -59,13 +60,13 @@ public class ShadowDialogTest {
@Test
public void shouldGetLayoutInflater() {
- Dialog dialog = new Dialog(RuntimeEnvironment.application);
+ Dialog dialog = new Dialog((Application) ApplicationProvider.getApplicationContext());
assertNotNull(dialog.getLayoutInflater());
}
@Test
public void shouldCallOnStartFromShow() {
- TestDialog dialog = new TestDialog(RuntimeEnvironment.application);
+ TestDialog dialog = new TestDialog((Application) ApplicationProvider.getApplicationContext());
dialog.show();
assertTrue(dialog.onStartCalled);
@@ -73,7 +74,7 @@ public class ShadowDialogTest {
@Test
public void shouldSetCancelable() {
- Dialog dialog = new Dialog(RuntimeEnvironment.application);
+ Dialog dialog = new Dialog((Application) ApplicationProvider.getApplicationContext());
ShadowDialog shadow = shadowOf(dialog);
dialog.setCancelable(false);
@@ -82,14 +83,14 @@ public class ShadowDialogTest {
@Test
public void shouldDismissTheRealDialogWhenCancelled() throws Exception {
- TestDialog dialog = new TestDialog(RuntimeEnvironment.application);
+ TestDialog dialog = new TestDialog((Application) ApplicationProvider.getApplicationContext());
dialog.cancel();
assertThat(dialog.wasDismissed).isTrue();
}
@Test
public void shouldDefaultCancelableToTrueAsTheSDKDoes() throws Exception {
- Dialog dialog = new Dialog(RuntimeEnvironment.application);
+ Dialog dialog = new Dialog((Application) ApplicationProvider.getApplicationContext());
ShadowDialog shadow = shadowOf(dialog);
assertThat(shadow.isCancelable()).isTrue();
@@ -99,13 +100,14 @@ public class ShadowDialogTest {
public void shouldOnlyCallOnCreateOnce() {
final List<String> transcript = new ArrayList<>();
- Dialog dialog = new Dialog(RuntimeEnvironment.application) {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- transcript.add("onCreate called");
- }
- };
+ Dialog dialog =
+ new Dialog((Application) ApplicationProvider.getApplicationContext()) {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ transcript.add("onCreate called");
+ }
+ };
dialog.show();
assertThat(transcript).containsExactly("onCreate called");
@@ -118,7 +120,7 @@ public class ShadowDialogTest {
@Test
public void show_setsLatestDialog() {
- Dialog dialog = new Dialog(RuntimeEnvironment.application);
+ Dialog dialog = new Dialog((Application) ApplicationProvider.getApplicationContext());
assertNull(ShadowDialog.getLatestDialog());
dialog.show();
@@ -131,7 +133,7 @@ public class ShadowDialogTest {
public void getLatestDialog_shouldReturnARealDialog() throws Exception {
assertThat(ShadowDialog.getLatestDialog()).isNull();
- Dialog dialog = new Dialog(RuntimeEnvironment.application);
+ Dialog dialog = new Dialog((Application) ApplicationProvider.getApplicationContext());
dialog.show();
assertThat(ShadowDialog.getLatestDialog()).isSameAs(dialog);
}
@@ -140,13 +142,13 @@ public class ShadowDialogTest {
public void shouldKeepListOfOpenedDialogs() throws Exception {
assertEquals(0, ShadowDialog.getShownDialogs().size());
- TestDialog dialog = new TestDialog(RuntimeEnvironment.application);
+ TestDialog dialog = new TestDialog((Application) ApplicationProvider.getApplicationContext());
dialog.show();
assertEquals(1, ShadowDialog.getShownDialogs().size());
assertEquals(dialog, ShadowDialog.getShownDialogs().get(0));
- TestDialog dialog2 = new TestDialog(RuntimeEnvironment.application);
+ TestDialog dialog2 = new TestDialog((Application) ApplicationProvider.getApplicationContext());
dialog2.show();
assertEquals(2, ShadowDialog.getShownDialogs().size());
@@ -170,7 +172,7 @@ public class ShadowDialogTest {
@Test
public void shouldFindViewsWithinAContentViewThatWasPreviouslySet() throws Exception {
- Dialog dialog = new Dialog(RuntimeEnvironment.application);
+ Dialog dialog = new Dialog((Application) ApplicationProvider.getApplicationContext());
dialog.setContentView(dialog.getLayoutInflater().inflate(R.layout.main, null));
assertThat(dialog.<TextView>findViewById(R.id.title)).isInstanceOf((Class<? extends TextView>) TextView.class);
}
@@ -178,13 +180,13 @@ public class ShadowDialogTest {
@Test
@Config(minSdk = KITKAT)
public void show_shouldWorkWithAPI19() {
- Dialog dialog = new Dialog(RuntimeEnvironment.application);
+ Dialog dialog = new Dialog((Application) ApplicationProvider.getApplicationContext());
dialog.show();
}
@Test
public void canSetAndGetOnCancelListener() {
- Dialog dialog = new Dialog(RuntimeEnvironment.application);
+ Dialog dialog = new Dialog((Application) ApplicationProvider.getApplicationContext());
DialogInterface.OnCancelListener onCancelListener = new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
@@ -216,7 +218,7 @@ public class ShadowDialogTest {
private static class NestingTestDialog extends Dialog {
public NestingTestDialog() {
- super(RuntimeEnvironment.application);
+ super((Application) ApplicationProvider.getApplicationContext());
}
@Override
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDiscoverySessionTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDiscoverySessionTest.java
index 52d1127ea..ff6fe22eb 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDiscoverySessionTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDiscoverySessionTest.java
@@ -4,13 +4,13 @@ import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
import android.net.wifi.aware.DiscoverySession;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** Tests for {@link ShadowDiscoverySession}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = O)
public class ShadowDiscoverySessionTest {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDisplayManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDisplayManagerTest.java
index 000b159f7..89595bc68 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDisplayManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDisplayManagerTest.java
@@ -7,6 +7,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.robolectric.shadows.ShadowDisplayManagerTest.HideFromJB.getGlobal;
+import android.app.Application;
import android.content.Context;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
@@ -14,25 +15,27 @@ import android.hardware.display.DisplayManagerGlobal;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowDisplayManagerTest {
private DisplayManager instance;
@Before
public void setUp() throws Exception {
- instance = (DisplayManager) RuntimeEnvironment.application
- .getSystemService(Context.DISPLAY_SERVICE);
+ instance =
+ (DisplayManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.DISPLAY_SERVICE);
}
@Test @Config(maxSdk = JELLY_BEAN)
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDisplayTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDisplayTest.java
index ed26fac86..a4be75c2b 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDisplayTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDisplayTest.java
@@ -9,14 +9,14 @@ import android.graphics.Rect;
import android.hardware.display.DisplayManagerGlobal;
import android.util.DisplayMetrics;
import android.view.Display;
+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.Shadows;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = JELLY_BEAN_MR1)
public class ShadowDisplayTest {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDownloadManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDownloadManagerTest.java
index 91bb34700..68fad1b5d 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDownloadManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDownloadManagerTest.java
@@ -9,12 +9,12 @@ import android.app.DownloadManager;
import android.database.Cursor;
import android.net.Uri;
import android.util.Pair;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowDownloadManagerTest {
private final Uri uri = Uri.parse("http://example.com/foo.mp4");
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDrawableTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDrawableTest.java
index e2378d98c..aa9aed7af 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDrawableTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDrawableTest.java
@@ -10,6 +10,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
@@ -17,16 +18,16 @@ import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.VectorDrawable;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowDrawableTest {
@Test
public void createFromStream__shouldReturnNullWhenAskedToCreateADrawableFromACorruptedSourceStream() throws Exception {
@@ -37,8 +38,13 @@ public class ShadowDrawableTest {
@Test
public void createFromResourceStream_shouldWorkWithoutSourceName() {
- Drawable drawable = Drawable.createFromResourceStream(RuntimeEnvironment.application.getResources(),
- null, new ByteArrayInputStream(new byte[0]), null, new BitmapFactory.Options());
+ Drawable drawable =
+ Drawable.createFromResourceStream(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ null,
+ new ByteArrayInputStream(new byte[0]),
+ null,
+ new BitmapFactory.Options());
assertNotNull(drawable);
}
@@ -118,8 +124,11 @@ public class ShadowDrawableTest {
}
@Test public void shouldLoadNinePatchFromDrawableXml() throws Exception {
- assertThat(RuntimeEnvironment.application.getResources()
- .getDrawable(R.drawable.drawable_with_nine_patch)).isNotNull();
+ assertThat(
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getDrawable(R.drawable.drawable_with_nine_patch))
+ .isNotNull();
}
@Test public void settingBoundsShouldInvokeCallback() {
@@ -131,7 +140,10 @@ public class ShadowDrawableTest {
@Test
public void drawableIntrinsicWidthAndHeightShouldBeCorrect() {
- final Drawable anImage = RuntimeEnvironment.application.getResources().getDrawable(R.drawable.an_image);
+ final Drawable anImage =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getDrawable(R.drawable.an_image);
assertThat(anImage.getIntrinsicHeight()).isEqualTo(53);
assertThat(anImage.getIntrinsicWidth()).isEqualTo(64);
@@ -140,7 +152,10 @@ public class ShadowDrawableTest {
@Test
@Config(qualifiers = "mdpi")
public void drawableShouldLoadImageOfCorrectSizeWithMdpiQualifier() {
- final Drawable anImage = RuntimeEnvironment.application.getResources().getDrawable(R.drawable.robolectric);
+ final Drawable anImage =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getDrawable(R.drawable.robolectric);
assertThat(anImage.getIntrinsicHeight()).isEqualTo(167);
assertThat(anImage.getIntrinsicWidth()).isEqualTo(198);
@@ -149,7 +164,10 @@ public class ShadowDrawableTest {
@Test
@Config(qualifiers = "hdpi")
public void drawableShouldLoadImageOfCorrectSizeWithHdpiQualifier() {
- final Drawable anImage = RuntimeEnvironment.application.getResources().getDrawable(R.drawable.robolectric);
+ final Drawable anImage =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getDrawable(R.drawable.robolectric);
assertThat(anImage.getIntrinsicHeight()).isEqualTo(251);
assertThat(anImage.getIntrinsicWidth()).isEqualTo(297);
@@ -160,16 +178,20 @@ public class ShadowDrawableTest {
public void testGetBitmapOrVectorDrawableAt19() {
// at API 21+ and mdpi, the drawable-anydpi-v21/image_or_vector.xml should be loaded instead
// of drawable/image_or_vector.png
- final Drawable aDrawable = RuntimeEnvironment.application.getResources()
- .getDrawable(R.drawable.an_image_or_vector);
+ final Drawable aDrawable =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getDrawable(R.drawable.an_image_or_vector);
assertThat(aDrawable).isInstanceOf(BitmapDrawable.class);
}
@Test
@Config(minSdk = LOLLIPOP)
public void testGetBitmapOrVectorDrawableAt21() {
- final Drawable aDrawable = RuntimeEnvironment.application.getResources()
- .getDrawable(R.drawable.an_image_or_vector);
+ final Drawable aDrawable =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getDrawable(R.drawable.an_image_or_vector);
assertThat(aDrawable).isInstanceOf(VectorDrawable.class);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowDropBoxManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowDropBoxManagerTest.java
index bab467c44..189c2ebe7 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowDropBoxManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowDropBoxManagerTest.java
@@ -3,19 +3,20 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.os.DropBoxManager;
import android.os.DropBoxManager.Entry;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
/** Unit tests for {@see ShadowDropboxManager}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowDropBoxManagerTest {
private static final String TAG = "TAG";
@@ -28,7 +29,9 @@ public class ShadowDropBoxManagerTest {
@Before
public void setup() {
manager =
- (DropBoxManager) RuntimeEnvironment.application.getSystemService(Context.DROPBOX_SERVICE);
+ (DropBoxManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.DROPBOX_SERVICE);
shadowDropBoxManager = shadowOf(manager);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowEditTextPreferenceTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowEditTextPreferenceTest.java
index 9fb0aaa1c..e414e3be7 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowEditTextPreferenceTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowEditTextPreferenceTest.java
@@ -4,16 +4,17 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import android.app.Application;
import android.content.Context;
import android.preference.EditTextPreference;
import android.widget.EditText;
+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 ShadowEditTextPreferenceTest {
private static final String SOME_TEXT = "some text";
@@ -23,7 +24,7 @@ public class ShadowEditTextPreferenceTest {
@Before
public void setup() {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
preference = new EditTextPreference(context);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowEditTextTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowEditTextTest.java
index 8a6077c43..606750f9e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowEditTextTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowEditTextTest.java
@@ -3,20 +3,21 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.RuntimeEnvironment.application;
+import android.app.Application;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.EditText;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Random;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowEditTextTest {
private EditText editText;
@@ -48,7 +49,8 @@ public class ShadowEditTextTest {
.addAttribute(android.R.attr.maxLength, maxLength + "")
.build();
- EditText editText = new EditText(RuntimeEnvironment.application, attrs);
+ EditText editText =
+ new EditText((Application) ApplicationProvider.getApplicationContext(), attrs);
String excessiveInput = stringOfLength(maxLength * 2);
editText.setText(excessiveInput);
@@ -59,7 +61,8 @@ public class ShadowEditTextTest {
@Test
public void givenInitializingWithAttributeSet_whenMaxLengthNotDefined_thenTextLengthShouldHaveNoRestrictions() {
AttributeSet attrs = Robolectric.buildAttributeSet().build();
- EditText editText = new EditText(RuntimeEnvironment.application, attrs);
+ EditText editText =
+ new EditText((Application) ApplicationProvider.getApplicationContext(), attrs);
String input = anyString();
editText.setText(input);
@@ -69,7 +72,7 @@ public class ShadowEditTextTest {
@Test
public void whenInitializingWithoutAttributeSet_thenTextLengthShouldHaveNoRestrictions() {
- EditText editText = new EditText(RuntimeEnvironment.application);
+ EditText editText = new EditText((Application) ApplicationProvider.getApplicationContext());
String input = anyString();
editText.setText(input);
@@ -79,7 +82,7 @@ public class ShadowEditTextTest {
@Test
public void testSelectAll() {
- EditText editText = new EditText(RuntimeEnvironment.application);
+ EditText editText = new EditText((Application) ApplicationProvider.getApplicationContext());
editText.setText("foo");
editText.selectAll();
@@ -90,7 +93,7 @@ public class ShadowEditTextTest {
@Test
public void shouldGetHintFromXml() {
- Context context = RuntimeEnvironment.application;
+ Context context = (Application) ApplicationProvider.getApplicationContext();
LayoutInflater inflater = LayoutInflater.from(context);
EditText editText = (EditText) inflater.inflate(R.layout.edit_text, null);
assertThat(editText.getHint().toString()).isEqualTo("Hello, Hint");
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowEnvironmentTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowEnvironmentTest.java
index 9733b6d97..5230bd5af 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowEnvironmentTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowEnvironmentTest.java
@@ -9,18 +9,19 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import android.app.Application;
import android.os.Environment;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import org.junit.After;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
-public class ShadowEnvironmentTest {
+@RunWith(AndroidJUnit4.class)
+public class ShadowEnvironmentTest {
@After
public void tearDown() throws Exception {
@@ -132,7 +133,8 @@ public class ShadowEnvironmentTest {
ShadowEnvironment.addExternalDir("external_dir_2");
File[] externalFilesDirs =
- RuntimeEnvironment.application.getExternalFilesDirs(Environment.DIRECTORY_MOVIES);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getExternalFilesDirs(Environment.DIRECTORY_MOVIES);
assertThat(externalFilesDirs).isNotEmpty();
assertThat(externalFilesDirs[0].getCanonicalPath()).contains("external_dir_1");
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowEuiccManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowEuiccManagerTest.java
index 8ff76a139..05918ea70 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowEuiccManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowEuiccManagerTest.java
@@ -5,15 +5,15 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.RuntimeEnvironment.application;
import android.telephony.euicc.EuiccManager;
+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.Shadows;
import org.robolectric.annotation.Config;
/** Junit test for {@link ShadowEuiccManager}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = P)
public class ShadowEuiccManagerTest {
private EuiccManager euiccManager;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowEventLogTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowEventLogTest.java
index f6529a474..fe20c45ad 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowEventLogTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowEventLogTest.java
@@ -5,14 +5,14 @@ import static org.robolectric.shadows.ShadowEventLog.NULL_PLACE_HOLDER;
import android.os.Build.VERSION_CODES;
import android.util.EventLog;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** Test ShadowEventLog */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowEventLogTest {
private static final String TEST_STRING1 = "hello";
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowExpandableListViewTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowExpandableListViewTest.java
index 4474ec4ea..997440832 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowExpandableListViewTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowExpandableListViewTest.java
@@ -1,20 +1,22 @@
package org.robolectric.shadows;
+import android.app.Application;
import android.widget.ExpandableListView;
+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 ShadowExpandableListViewTest {
private ExpandableListView expandableListView;
@Before
public void setUp() {
- expandableListView = new ExpandableListView(RuntimeEnvironment.application);
+ expandableListView =
+ new ExpandableListView((Application) ApplicationProvider.getApplicationContext());
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowFilterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowFilterTest.java
index 8a396d16a..fb30b1daa 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowFilterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowFilterTest.java
@@ -3,12 +3,12 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.widget.Filter;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowFilterTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowFingerprintManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowFingerprintManagerTest.java
index 5e6aae34b..3d8fde52c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowFingerprintManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowFingerprintManagerTest.java
@@ -6,21 +6,22 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
import android.hardware.fingerprint.FingerprintManager.CryptoObject;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.security.Signature;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = M)
public class ShadowFingerprintManagerTest {
@@ -28,8 +29,10 @@ public class ShadowFingerprintManagerTest {
@Before
public void setUp() {
- manager = (FingerprintManager) RuntimeEnvironment.application
- .getSystemService(Context.FINGERPRINT_SERVICE);
+ manager =
+ (FingerprintManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.FINGERPRINT_SERVICE);
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowFrameLayoutTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowFrameLayoutTest.java
index 77c2e7655..bf8207a41 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowFrameLayoutTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowFrameLayoutTest.java
@@ -3,22 +3,23 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNotNull;
+import android.app.Application;
import android.view.View;
import android.widget.FrameLayout;
+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 ShadowFrameLayoutTest {
private FrameLayout frameLayout;
@Before
public void setUp() throws Exception {
- frameLayout = new FrameLayout(RuntimeEnvironment.application);
+ frameLayout = new FrameLayout((Application) ApplicationProvider.getApplicationContext());
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowGLES20Test.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowGLES20Test.java
index a5b89e224..0ac6d8141 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowGLES20Test.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowGLES20Test.java
@@ -3,18 +3,22 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.opengl.GLES20;
-
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-/**
- * Test for {@link GLES20}
- */
-@RunWith(RobolectricTestRunner.class)
+/** Test for {@link GLES20} */
+@RunWith(AndroidJUnit4.class)
public final class ShadowGLES20Test {
@Test
+ public void glGenFramebuffers() {
+ int[] framebuffers = new int[1];
+ GLES20.glGenFramebuffers(1, framebuffers, 0);
+ assertThat(framebuffers[0]).isAtLeast(1);
+ }
+
+ @Test
public void glGenTextures() {
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
@@ -35,4 +39,18 @@ public final class ShadowGLES20Test {
public void glCreateProgram() {
assertThat(GLES20.glCreateProgram()).isAtLeast(1);
}
+
+ @Test
+ public void glGetShaderiv_compileStatus() {
+ int[] params = new int[1];
+ GLES20.glGetShaderiv(1, GLES20.GL_COMPILE_STATUS, params, 0);
+ assertThat(params[0]).isEqualTo(GLES20.GL_TRUE);
+ }
+
+ @Test
+ public void glGetProgramiv_compileStatus() {
+ int[] params = new int[1];
+ GLES20.glGetProgramiv(1, GLES20.GL_LINK_STATUS, params, 0);
+ assertThat(params[0]).isEqualTo(GLES20.GL_TRUE);
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowGeocoderTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowGeocoderTest.java
index 79c08d7c1..f298d9e40 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowGeocoderTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowGeocoderTest.java
@@ -4,19 +4,20 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.location.Address;
import android.location.Geocoder;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
/** Unit test for {@link ShadowGeocoder}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowGeocoderTest {
@Test
@@ -33,13 +34,17 @@ public class ShadowGeocoderTest {
@Test
public void getFromLocationReturnsAnEmptyArrayByDefault() throws IOException {
- Geocoder geocoder = new Geocoder(RuntimeEnvironment.application.getApplicationContext());
+ Geocoder geocoder =
+ new Geocoder(
+ ((Application) ApplicationProvider.getApplicationContext()).getApplicationContext());
assertThat(geocoder.getFromLocation(90.0,90.0,1)).hasSize(0);
}
@Test
public void getFromLocationReturnsTheOverwrittenListLimitingByMaxResults() throws IOException {
- Geocoder geocoder = new Geocoder(RuntimeEnvironment.application.getApplicationContext());
+ Geocoder geocoder =
+ new Geocoder(
+ ((Application) ApplicationProvider.getApplicationContext()).getApplicationContext());
ShadowGeocoder shadowGeocoder = shadowOf(geocoder);
List<Address> list = Arrays.asList(new Address(Locale.getDefault()), new Address(Locale.CANADA));
@@ -57,7 +62,9 @@ public class ShadowGeocoderTest {
@Test
public void getFromLocation_throwsExceptionForInvalidLatitude() throws IOException {
- Geocoder geocoder = new Geocoder(RuntimeEnvironment.application.getApplicationContext());
+ Geocoder geocoder =
+ new Geocoder(
+ ((Application) ApplicationProvider.getApplicationContext()).getApplicationContext());
try {
geocoder.getFromLocation(91.0, 90.0, 1);
@@ -69,7 +76,9 @@ public class ShadowGeocoderTest {
@Test
public void getFromLocation_throwsExceptionForInvalidLongitude() throws IOException {
- Geocoder geocoder = new Geocoder(RuntimeEnvironment.application.getApplicationContext());
+ Geocoder geocoder =
+ new Geocoder(
+ ((Application) ApplicationProvider.getApplicationContext()).getApplicationContext());
try {
geocoder.getFromLocation(15.0, -211.0, 1);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowGestureDetectorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowGestureDetectorTest.java
new file mode 100644
index 000000000..c3316bccb
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowGestureDetectorTest.java
@@ -0,0 +1,130 @@
+package org.robolectric.shadows;
+
+import static androidx.test.core.view.MotionEventBuilder.newBuilder;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.app.Application;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+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;
+
+@RunWith(AndroidJUnit4.class)
+public class ShadowGestureDetectorTest {
+
+ private GestureDetector detector;
+ private MotionEvent motionEvent;
+
+ @Before
+ public void setUp() throws Exception {
+ detector = new GestureDetector(new TestOnGestureListener());
+ motionEvent = newBuilder().setAction(MotionEvent.ACTION_UP).setPointer(100, 30).build();
+ }
+
+ @Test
+ public void test_getOnTouchEventMotionEvent() throws Exception {
+ detector.onTouchEvent(motionEvent);
+ assertSame(motionEvent, shadowOf(detector).getOnTouchEventMotionEvent());
+ }
+
+ @Test
+ public void test_reset() throws Exception {
+ detector.onTouchEvent(motionEvent);
+ assertSame(motionEvent, shadowOf(detector).getOnTouchEventMotionEvent());
+
+ shadowOf(detector).reset();
+ assertNull(shadowOf(detector).getOnTouchEventMotionEvent());
+ }
+
+ @Test
+ public void test_getListener() throws Exception {
+ TestOnGestureListener listener = new TestOnGestureListener();
+ assertSame(listener, shadowOf(new GestureDetector(listener)).getListener());
+ assertSame(listener, shadowOf(new GestureDetector(null, listener)).getListener());
+ }
+
+ @Test
+ public void canAnswerLastGestureDetector() throws Exception {
+ GestureDetector newDetector =
+ new GestureDetector(
+ (Application) ApplicationProvider.getApplicationContext(), new TestOnGestureListener());
+ assertNotSame(newDetector, ShadowGestureDetector.getLastActiveDetector());
+ newDetector.onTouchEvent(motionEvent);
+ assertSame(newDetector, ShadowGestureDetector.getLastActiveDetector());
+ }
+
+ @Test
+ public void getOnDoubleTapListener_shouldReturnSetDoubleTapListener() throws Exception {
+ GestureDetector subject =
+ new GestureDetector(
+ (Application) ApplicationProvider.getApplicationContext(), new TestOnGestureListener());
+ GestureDetector.OnDoubleTapListener onDoubleTapListener = new GestureDetector.OnDoubleTapListener() {
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent e) {
+ return false;
+ }
+
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ return false;
+ }
+
+ @Override
+ public boolean onDoubleTapEvent(MotionEvent e) {
+ return false;
+ }
+ };
+
+ subject.setOnDoubleTapListener(onDoubleTapListener);
+ assertEquals(shadowOf(subject).getOnDoubleTapListener(), onDoubleTapListener);
+
+ subject.setOnDoubleTapListener(null);
+ assertEquals(shadowOf(subject).getOnDoubleTapListener(), null);
+ }
+
+ @Test
+ public void getOnDoubleTapListener_shouldReturnOnGestureListenerFromConstructor() throws Exception {
+ GestureDetector.OnGestureListener onGestureListener = new GestureDetector.SimpleOnGestureListener();
+ GestureDetector subject =
+ new GestureDetector(
+ (Application) ApplicationProvider.getApplicationContext(), onGestureListener);
+ assertEquals(shadowOf(subject).getOnDoubleTapListener(), onGestureListener);
+ }
+
+ private static class TestOnGestureListener implements GestureDetector.OnGestureListener {
+ @Override
+ public boolean onDown(MotionEvent e) {
+ return false;
+ }
+
+ @Override
+ public void onShowPress(MotionEvent e) {
+ }
+
+ @Override
+ public boolean onSingleTapUp(MotionEvent e) {
+ return false;
+ }
+
+ @Override
+ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+ return false;
+ }
+
+ @Override
+ public void onLongPress(MotionEvent e) {
+ }
+
+ @Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+ return false;
+ }
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowGradientDrawableTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowGradientDrawableTest.java
index f249f7f30..d56b3c5da 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowGradientDrawableTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowGradientDrawableTest.java
@@ -4,11 +4,11 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.graphics.drawable.GradientDrawable;
+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 ShadowGradientDrawableTest {
@Test
public void testGetColor_returnsColor() throws Exception {
@@ -16,6 +16,6 @@ public class ShadowGradientDrawableTest {
ShadowGradientDrawable shadowGradientDrawable = shadowOf(gradientDrawable);
int color = 123;
gradientDrawable.setColor(color);
- assertThat(shadowGradientDrawable.getColor()).isEqualTo(color);
+ assertThat(shadowGradientDrawable.getLastSetColor()).isEqualTo(color);
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowHandlerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowHandlerTest.java
index e0c3d039e..ac8d3a2fd 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowHandlerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowHandlerTest.java
@@ -9,18 +9,18 @@ import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.Scheduler;
import org.robolectric.util.TestRunnable;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowHandlerTest {
private List<String> transcript;
TestRunnable scratchRunnable = new TestRunnable();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowHandlerThreadTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowHandlerThreadTest.java
index a33b046b1..cde9f6bf1 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowHandlerThreadTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowHandlerThreadTest.java
@@ -7,17 +7,18 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.os.HandlerThread;
import android.os.Looper;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.junit.After;
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 ShadowHandlerThreadTest {
private HandlerThread handlerThread;
@@ -36,7 +37,9 @@ public class ShadowHandlerThreadTest {
handlerThread = new HandlerThread("test");
handlerThread.start();
assertNotNull(handlerThread.getLooper());
- assertNotSame(handlerThread.getLooper(), RuntimeEnvironment.application.getMainLooper());
+ assertNotSame(
+ handlerThread.getLooper(),
+ ((Application) ApplicationProvider.getApplicationContext()).getMainLooper());
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowHtmlTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowHtmlTest.java
index 5f253e974..1005063e8 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowHtmlTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowHtmlTest.java
@@ -5,20 +5,21 @@ import static android.os.Build.VERSION_CODES.N;
import static com.google.common.truth.Truth.assertThat;
import android.annotation.TargetApi;
+import android.app.Application;
import android.content.Context;
import android.text.Html;
import android.text.Spanned;
import android.widget.EditText;
import android.widget.TextView;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowHtmlTest {
private static final String HTML_SHORT = "<img src='foo.png'>";
private static final String HTML_LONG = String.format("<img src='%s.png'>",
@@ -28,7 +29,7 @@ public class ShadowHtmlTest {
@Before
public void setUp() throws Exception {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowHttpResponseCacheTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowHttpResponseCacheTest.java
index aa33cb543..48ee23120 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowHttpResponseCacheTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowHttpResponseCacheTest.java
@@ -3,14 +3,14 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.net.http.HttpResponseCache;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import org.junit.After;
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 ShadowHttpResponseCacheTest {
@Before
public void setUp() {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowICUTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowICUTest.java
index cbe7fee70..c84c56a39 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowICUTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowICUTest.java
@@ -7,16 +7,16 @@ import android.app.Activity;
import android.os.Bundle;
import android.widget.DatePicker;
import android.widget.LinearLayout;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Locale;
import libcore.icu.ICU;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowICUTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowIconTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowIconTest.java
index 49d706b5c..75e8b264f 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowIconTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowIconTest.java
@@ -4,16 +4,17 @@ import static android.os.Build.VERSION_CODES.M;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
import android.net.Uri;
+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;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = M)
public class ShadowIconTest {
public static final int TYPE_BITMAP = 1;
@@ -23,7 +24,10 @@ public class ShadowIconTest {
@Test
public void testGetRes() {
- Icon icon = Icon.createWithResource(RuntimeEnvironment.application, android.R.drawable.ic_delete);
+ Icon icon =
+ Icon.createWithResource(
+ (Application) ApplicationProvider.getApplicationContext(),
+ android.R.drawable.ic_delete);
assertThat(shadowOf(icon).getType()).isEqualTo(TYPE_RESOURCE);
assertThat(shadowOf(icon).getResId()).isEqualTo(android.R.drawable.ic_delete);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowImageViewTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowImageViewTest.java
index 81afe343b..de4eec30a 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowImageViewTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowImageViewTest.java
@@ -3,25 +3,27 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;
+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.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowImageViewTest {
@Test
public void getDrawableResourceId_shouldWorkWhenTheDrawableWasCreatedFromAResource() throws Exception {
- Resources resources = RuntimeEnvironment.application.getResources();
+ Resources resources =
+ ((Application) ApplicationProvider.getApplicationContext()).getResources();
Bitmap bitmap = BitmapFactory.decodeResource(resources, R.drawable.an_image);
- ImageView imageView = new ImageView(RuntimeEnvironment.application);
+ ImageView imageView = new ImageView((Application) ApplicationProvider.getApplicationContext());
imageView.setImageBitmap(bitmap);
imageView.setImageResource(R.drawable.an_image);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowInputDeviceTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowInputDeviceTest.java
index 43e14b5f1..ad1d22698 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowInputDeviceTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowInputDeviceTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.view.InputDevice;
+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 ShadowInputDeviceTest {
@Test
public void canConstructInputDeviceWithName() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowInputEventTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowInputEventTest.java
index bf8f884be..2fa4f8c89 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowInputEventTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowInputEventTest.java
@@ -5,11 +5,11 @@ import static org.robolectric.Shadows.shadowOf;
import android.view.InputDevice;
import android.view.KeyEvent;
+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 ShadowInputEventTest {
@Test
public void canSetInputDeviceOnKeyEvent() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowInputMethodManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowInputMethodManagerTest.java
index 08917313e..d85c2b6ff 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowInputMethodManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowInputMethodManagerTest.java
@@ -5,15 +5,16 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import android.app.Activity;
+import android.app.Application;
import android.view.inputmethod.InputMethodManager;
+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;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowInputMethodManagerTest {
private InputMethodManager manager;
@@ -21,7 +22,10 @@ public class ShadowInputMethodManagerTest {
@Before
public void setUp() throws Exception {
- manager = (InputMethodManager) RuntimeEnvironment.application.getSystemService(Activity.INPUT_METHOD_SERVICE);
+ manager =
+ (InputMethodManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Activity.INPUT_METHOD_SERVICE);
shadow = Shadows.shadowOf(manager);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentFilterAuthorityEntryTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentFilterAuthorityEntryTest.java
index 48e7161cb..11fb70392 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentFilterAuthorityEntryTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentFilterAuthorityEntryTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.content.IntentFilter;
+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 ShadowIntentFilterAuthorityEntryTest {
@Test(expected = NumberFormatException.class)
public void constructor_shouldThrowAnExceptionIfPortIsNotAValidNumber() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentFilterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentFilterTest.java
index fbf795157..132c3727c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentFilterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentFilterTest.java
@@ -4,11 +4,11 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.IntentFilter;
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 ShadowIntentFilterTest {
@Test
public void copyConstructorTest() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentServiceTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentServiceTest.java
index 8dec5d017..86d6bf46e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentServiceTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentServiceTest.java
@@ -5,11 +5,11 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.IntentService;
import android.content.Intent;
+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 ShadowIntentServiceTest {
@Test
public void shouldSetIntentRedelivery() {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentTest.java
index 3000d5247..532863b67 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowIntentTest.java
@@ -8,6 +8,7 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import android.app.Activity;
+import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -17,28 +18,28 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Set;
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 ShadowIntentTest {
private static final String TEST_ACTIVITY_CLASS_NAME = "org.robolectric.shadows.TestActivity";
@Test
public void resolveActivityInfo_shouldReturnActivityInfoForExistingActivity() {
- Context context = RuntimeEnvironment.application;
- PackageManager packageManager = context.getPackageManager();
+ Context context = (Application) ApplicationProvider.getApplicationContext();
+ PackageManager packageManager = context.getPackageManager();
- Intent intent = new Intent();
- intent.setClassName(context, TEST_ACTIVITY_CLASS_NAME);
- ActivityInfo activityInfo = intent.resolveActivityInfo(packageManager, PackageManager.GET_ACTIVITIES);
- assertThat(activityInfo).isNotNull();
+ Intent intent = new Intent();
+ intent.setClassName(context, TEST_ACTIVITY_CLASS_NAME);
+ ActivityInfo activityInfo = intent.resolveActivityInfo(packageManager, PackageManager.GET_ACTIVITIES);
+ assertThat(activityInfo).isNotNull();
}
@Test
@@ -205,7 +206,7 @@ public class ShadowIntentTest {
assertSame(uri, intent.getData());
assertNull(intent.getType());
}
-
+
@Test
public void testGetScheme() throws Exception {
Intent intent = new Intent();
@@ -237,7 +238,8 @@ public class ShadowIntentTest {
public void testSetClass() throws Exception {
Intent intent = new Intent();
Class<? extends ShadowIntentTest> thisClass = getClass();
- Intent output = intent.setClass(RuntimeEnvironment.application, thisClass);
+ Intent output =
+ intent.setClass((Application) ApplicationProvider.getApplicationContext(), thisClass);
assertSame(output, intent);
assertThat(intent.getComponent().getClassName()).isEqualTo(thisClass.getName());
@@ -255,7 +257,8 @@ public class ShadowIntentTest {
@Test
public void testSetClassThroughConstructor() throws Exception {
- Intent intent = new Intent(RuntimeEnvironment.application, getClass());
+ Intent intent =
+ new Intent((Application) ApplicationProvider.getApplicationContext(), getClass());
assertThat(intent.getComponent().getClassName()).isEqualTo(getClass().getName());
}
@@ -393,7 +396,12 @@ public class ShadowIntentTest {
@Test
public void constructor_shouldSetComponentAndActionAndData() {
- Intent intent = new Intent("roboaction", Uri.parse("http://www.robolectric.org"), RuntimeEnvironment.application, Activity.class);
+ Intent intent =
+ new Intent(
+ "roboaction",
+ Uri.parse("http://www.robolectric.org"),
+ (Application) ApplicationProvider.getApplicationContext(),
+ Activity.class);
assertThat(intent.getComponent()).isEqualTo(new ComponentName("org.robolectric", "android.app.Activity"));
assertThat(intent.getAction()).isEqualTo("roboaction");
assertThat(intent.getData()).isEqualTo(Uri.parse("http://www.robolectric.org"));
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowIoUtilsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowIoUtilsTest.java
index d8c4b7e50..f75203c86 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowIoUtilsTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowIoUtilsTest.java
@@ -2,6 +2,7 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.io.Files;
import java.io.File;
import java.nio.charset.StandardCharsets;
@@ -10,9 +11,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowIoUtilsTest {
@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowJobSchedulerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowJobSchedulerTest.java
index e5faee422..4901f4872 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowJobSchedulerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowJobSchedulerTest.java
@@ -6,20 +6,21 @@ import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.app.job.JobWorkItem;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+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;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowJobSchedulerTest {
@@ -27,15 +28,22 @@ public class ShadowJobSchedulerTest {
@Before
public void setUp() {
- jobScheduler = (JobScheduler) RuntimeEnvironment.application.getSystemService(Context.JOB_SCHEDULER_SERVICE);
+ jobScheduler =
+ (JobScheduler)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.JOB_SCHEDULER_SERVICE);
}
@Test
public void getAllPendingJobs() {
- JobInfo jobInfo = new JobInfo.Builder(99,
- new ComponentName(RuntimeEnvironment.application, "component_class_name"))
- .setPeriodic(1000)
- .build();
+ JobInfo jobInfo =
+ new JobInfo.Builder(
+ 99,
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "component_class_name"))
+ .setPeriodic(1000)
+ .build();
jobScheduler.schedule(jobInfo);
assertThat(jobScheduler.getAllPendingJobs()).contains(jobInfo);
@@ -43,14 +51,22 @@ public class ShadowJobSchedulerTest {
@Test
public void cancelAll() {
- jobScheduler.schedule(new JobInfo.Builder(99,
- new ComponentName(RuntimeEnvironment.application, "component_class_name"))
- .setPeriodic(1000)
- .build());
- jobScheduler.schedule(new JobInfo.Builder(33,
- new ComponentName(RuntimeEnvironment.application, "component_class_name"))
- .setPeriodic(1000)
- .build());
+ jobScheduler.schedule(
+ new JobInfo.Builder(
+ 99,
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "component_class_name"))
+ .setPeriodic(1000)
+ .build());
+ jobScheduler.schedule(
+ new JobInfo.Builder(
+ 33,
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "component_class_name"))
+ .setPeriodic(1000)
+ .build());
assertThat(jobScheduler.getAllPendingJobs()).hasSize(2);
@@ -61,10 +77,14 @@ public class ShadowJobSchedulerTest {
@Test
public void cancelSingleJob() {
- jobScheduler.schedule(new JobInfo.Builder(99,
- new ComponentName(RuntimeEnvironment.application, "component_class_name"))
- .setPeriodic(1000)
- .build());
+ jobScheduler.schedule(
+ new JobInfo.Builder(
+ 99,
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "component_class_name"))
+ .setPeriodic(1000)
+ .build());
assertThat(jobScheduler.getAllPendingJobs()).isNotEmpty();
@@ -75,10 +95,14 @@ public class ShadowJobSchedulerTest {
@Test
public void cancelNonExistentJob() {
- jobScheduler.schedule(new JobInfo.Builder(99,
- new ComponentName(RuntimeEnvironment.application, "component_class_name"))
- .setPeriodic(1000)
- .build());
+ jobScheduler.schedule(
+ new JobInfo.Builder(
+ 99,
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "component_class_name"))
+ .setPeriodic(1000)
+ .build());
assertThat(jobScheduler.getAllPendingJobs()).isNotEmpty();
@@ -89,10 +113,15 @@ public class ShadowJobSchedulerTest {
@Test
public void schedule_success() {
- int result = jobScheduler.schedule(new JobInfo.Builder(99,
- new ComponentName(RuntimeEnvironment.application, "component_class_name"))
- .setPeriodic(1000)
- .build());
+ int result =
+ jobScheduler.schedule(
+ new JobInfo.Builder(
+ 99,
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "component_class_name"))
+ .setPeriodic(1000)
+ .build());
assertThat(result).isEqualTo(JobScheduler.RESULT_SUCCESS);
}
@@ -100,10 +129,15 @@ public class ShadowJobSchedulerTest {
public void schedule_fail() {
shadowOf(jobScheduler).failOnJob(99);
- int result = jobScheduler.schedule(new JobInfo.Builder(99,
- new ComponentName(RuntimeEnvironment.application, "component_class_name"))
- .setPeriodic(1000)
- .build());
+ int result =
+ jobScheduler.schedule(
+ new JobInfo.Builder(
+ 99,
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "component_class_name"))
+ .setPeriodic(1000)
+ .build());
assertThat(result).isEqualTo(JobScheduler.RESULT_FAILURE);
}
@@ -112,10 +146,14 @@ public class ShadowJobSchedulerTest {
@Config(minSdk = N)
public void getPendingJob_withValidId() {
int jobId = 99;
- JobInfo originalJobInfo = new JobInfo.Builder(jobId,
- new ComponentName(RuntimeEnvironment.application, "component_class_name"))
- .setPeriodic(1000)
- .build();
+ JobInfo originalJobInfo =
+ new JobInfo.Builder(
+ jobId,
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "component_class_name"))
+ .setPeriodic(1000)
+ .build();
jobScheduler.schedule(originalJobInfo);
@@ -129,10 +167,14 @@ public class ShadowJobSchedulerTest {
public void getPendingJob_withInvalidId() {
int jobId = 99;
int invalidJobId = 100;
- JobInfo originalJobInfo = new JobInfo.Builder(jobId,
- new ComponentName(RuntimeEnvironment.application, "component_class_name"))
- .setPeriodic(1000)
- .build();
+ JobInfo originalJobInfo =
+ new JobInfo.Builder(
+ jobId,
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "component_class_name"))
+ .setPeriodic(1000)
+ .build();
jobScheduler.schedule(originalJobInfo);
@@ -147,7 +189,10 @@ public class ShadowJobSchedulerTest {
int result =
jobScheduler.enqueue(
new JobInfo.Builder(
- 99, new ComponentName(RuntimeEnvironment.application, "component_class_name"))
+ 99,
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "component_class_name"))
.setPeriodic(1000)
.build(),
new JobWorkItem(new Intent()));
@@ -162,7 +207,10 @@ public class ShadowJobSchedulerTest {
int result =
jobScheduler.enqueue(
new JobInfo.Builder(
- 99, new ComponentName(RuntimeEnvironment.application, "component_class_name"))
+ 99,
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "component_class_name"))
.setPeriodic(1000)
.build(),
new JobWorkItem(new Intent()));
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowJobServiceTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowJobServiceTest.java
index b157593ce..8fca386d0 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowJobServiceTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowJobServiceTest.java
@@ -6,18 +6,16 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.job.JobParameters;
import android.app.job.JobService;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-/**
- * Robolectric test for {@link ShadowJobService}.
- */
-@RunWith(RobolectricTestRunner.class)
+/** Robolectric test for {@link ShadowJobService}. */
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowJobServiceTest {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowJsPromptResultTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowJsPromptResultTest.java
index 7f841e85b..f4a619adc 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowJsPromptResultTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowJsPromptResultTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static org.junit.Assert.assertNotNull;
import android.webkit.JsPromptResult;
+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 ShadowJsPromptResultTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowJsResultTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowJsResultTest.java
index 245ce5e61..3128d6d87 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowJsResultTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowJsResultTest.java
@@ -5,12 +5,12 @@ import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
import android.webkit.JsResult;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowJsResultTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowJsonReaderTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowJsonReaderTest.java
index b79b7228b..8a6f716cf 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowJsonReaderTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowJsonReaderTest.java
@@ -3,12 +3,12 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.util.JsonReader;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.StringReader;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowJsonReaderTest {
@Test public void shouldWork() throws Exception {
JsonReader jsonReader = new JsonReader(new StringReader("{\"abc\": \"def\"}"));
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowKeyCharacterMapTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowKeyCharacterMapTest.java
index 8920fcce2..92c181548 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowKeyCharacterMapTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowKeyCharacterMapTest.java
@@ -2,21 +2,22 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.widget.EditText;
+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 ShadowKeyCharacterMapTest {
private final KeyCharacterMap keyMap = ShadowKeyCharacterMap.load(0);
@Test
public void dispatchKeyEvent_shouldSetText() throws Exception {
- EditText editText = new EditText(RuntimeEnvironment.application);
+ EditText editText = new EditText((Application) ApplicationProvider.getApplicationContext());
editText.requestFocus();
for (KeyEvent evt : keyMap.getEvents("string".toCharArray())) {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowKeyguardManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowKeyguardManagerTest.java
index 464a11d67..11d066f26 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowKeyguardManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowKeyguardManagerTest.java
@@ -10,17 +10,18 @@ import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
+import android.app.Application;
import android.app.KeyguardManager;
import android.app.KeyguardManager.KeyguardDismissCallback;
+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.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowKeyguardManagerTest {
private static final int USER_ID = 1001;
@@ -28,7 +29,10 @@ public class ShadowKeyguardManagerTest {
@Before
public void setUp() {
- manager = (KeyguardManager) RuntimeEnvironment.application.getSystemService(KEYGUARD_SERVICE);
+ manager =
+ (KeyguardManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(KEYGUARD_SERVICE);
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowLayerDrawableTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowLayerDrawableTest.java
index 1e7ee9027..fa347d0b4 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowLayerDrawableTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowLayerDrawableTest.java
@@ -5,18 +5,19 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
+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.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowLayerDrawableTest {
/**
* drawables
@@ -33,14 +34,26 @@ public class ShadowLayerDrawableTest {
@Before
public void setUp() {
- drawable1000 = new BitmapDrawable(BitmapFactory.decodeResource(
- RuntimeEnvironment.application.getResources(), R.drawable.an_image));
- drawable2000 = new BitmapDrawable(BitmapFactory.decodeResource(
- RuntimeEnvironment.application.getResources(), R.drawable.an_other_image));
- drawable3000 = new BitmapDrawable(BitmapFactory.decodeResource(
- RuntimeEnvironment.application.getResources(), R.drawable.third_image));
- drawable4000 = new BitmapDrawable(BitmapFactory.decodeResource(
- RuntimeEnvironment.application.getResources(), R.drawable.fourth_image));
+ drawable1000 =
+ new BitmapDrawable(
+ BitmapFactory.decodeResource(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ R.drawable.an_image));
+ drawable2000 =
+ new BitmapDrawable(
+ BitmapFactory.decodeResource(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ R.drawable.an_other_image));
+ drawable3000 =
+ new BitmapDrawable(
+ BitmapFactory.decodeResource(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ R.drawable.third_image));
+ drawable4000 =
+ new BitmapDrawable(
+ BitmapFactory.decodeResource(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ R.drawable.fourth_image));
drawables = new Drawable[]{drawable1000, drawable2000, drawable3000};
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutAnimationControllerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutAnimationControllerTest.java
index 3086197b7..541ca1e3f 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutAnimationControllerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutAnimationControllerTest.java
@@ -2,21 +2,24 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.view.animation.LayoutAnimationController;
+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;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowLayoutAnimationControllerTest {
private ShadowLayoutAnimationController shadow;
@Before
public void setup() {
- LayoutAnimationController controller = new LayoutAnimationController(RuntimeEnvironment.application, null);
+ LayoutAnimationController controller =
+ new LayoutAnimationController(
+ (Application) ApplicationProvider.getApplicationContext(), null);
shadow = Shadows.shadowOf(controller);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutInflaterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutInflaterTest.java
index daf59fabf..403468e4c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutInflaterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutInflaterTest.java
@@ -11,6 +11,7 @@ import static org.robolectric.Robolectric.buildActivity;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
+import android.app.Application;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.drawable.BitmapDrawable;
@@ -30,26 +31,26 @@ import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
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.R;
import org.robolectric.R.layout;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.CustomStateView;
import org.robolectric.android.CustomView;
import org.robolectric.android.CustomView2;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowLayoutInflaterTest {
private Context context;
@Before
public void setUp() throws Exception {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutParamsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutParamsTest.java
index 5e24edaad..81c5c1847 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutParamsTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowLayoutParamsTest.java
@@ -5,11 +5,11 @@ import static com.google.common.truth.Truth.assertThat;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.Gallery;
+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 ShadowLayoutParamsTest {
@Test
public void testConstructor() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowLinearLayoutTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowLinearLayoutTest.java
index 1f683636a..75df1238c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowLinearLayoutTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowLinearLayoutTest.java
@@ -4,22 +4,23 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertSame;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.view.Gravity;
import android.widget.LinearLayout;
+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 ShadowLinearLayoutTest {
private LinearLayout linearLayout;
private ShadowLinearLayout shadow;
@Before
public void setup() throws Exception {
- linearLayout = new LinearLayout(RuntimeEnvironment.application);
+ linearLayout = new LinearLayout((Application) ApplicationProvider.getApplicationContext());
shadow = shadowOf(linearLayout);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowLinkMovementMethodTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowLinkMovementMethodTest.java
index b35270b3e..cc26fd537 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowLinkMovementMethodTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowLinkMovementMethodTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.text.method.LinkMovementMethod;
+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 ShadowLinkMovementMethodTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowListPopupWindowTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowListPopupWindowTest.java
index b41966a01..5bdca66e3 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowListPopupWindowTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowListPopupWindowTest.java
@@ -2,19 +2,20 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.content.Context;
import android.view.View;
import android.widget.ListPopupWindow;
+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 ShadowListPopupWindowTest {
@Test
public void show_setsLastListPopupWindow() throws Exception {
- Context context = RuntimeEnvironment.application;
+ Context context = (Application) ApplicationProvider.getApplicationContext();
ListPopupWindow popupWindow = new ListPopupWindow(context);
assertThat(ShadowListPopupWindow.getLatestListPopupWindow()).isNull();
popupWindow.setAnchorView(new View(context));
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowListPreferenceTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowListPreferenceTest.java
index 4adb1f9a7..36a6f2f3b 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowListPreferenceTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowListPreferenceTest.java
@@ -5,13 +5,13 @@ import static org.robolectric.Robolectric.buildActivity;
import android.app.Activity;
import android.preference.ListPreference;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowListPreferenceTest {
private ListPreference listPreference;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowListViewAdapterViewBehaviorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowListViewAdapterViewBehaviorTest.java
index 92bd3bfc5..72b992988 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowListViewAdapterViewBehaviorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowListViewAdapterViewBehaviorTest.java
@@ -1,14 +1,15 @@
package org.robolectric.shadows;
+import android.app.Application;
import android.widget.AdapterView;
import android.widget.ListView;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowListViewAdapterViewBehaviorTest extends AdapterViewBehavior {
@Override public AdapterView createAdapterView() {
- return new ListView(RuntimeEnvironment.application);
+ return new ListView((Application) ApplicationProvider.getApplicationContext());
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowListViewTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowListViewTest.java
index 3b5642817..f45e4cffa 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowListViewTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowListViewTest.java
@@ -7,6 +7,7 @@ import static org.junit.Assert.assertNull;
import static org.robolectric.RuntimeEnvironment.application;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.util.SparseBooleanArray;
import android.view.View;
import android.view.ViewGroup;
@@ -16,17 +17,17 @@ import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.util.ReflectionHelpers;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowListViewTest {
private List<String> transcript;
@@ -38,18 +39,18 @@ public class ShadowListViewTest {
@Before
public void setUp() throws Exception {
transcript = new ArrayList<>();
- listView = new ListView(RuntimeEnvironment.application);
+ listView = new ListView((Application) ApplicationProvider.getApplicationContext());
}
@Test
public void addHeaderView_ShouldRecordHeaders() throws Exception {
- View view0 = new View(RuntimeEnvironment.application);
+ View view0 = new View((Application) ApplicationProvider.getApplicationContext());
view0.setId(0);
- View view1 = new View(RuntimeEnvironment.application);
+ View view1 = new View((Application) ApplicationProvider.getApplicationContext());
view1.setId(1);
- View view2 = new View(RuntimeEnvironment.application);
+ View view2 = new View((Application) ApplicationProvider.getApplicationContext());
view2.setId(2);
- View view3 = new View(RuntimeEnvironment.application);
+ View view3 = new View((Application) ApplicationProvider.getApplicationContext());
view3.setId(3);
listView.addHeaderView(view0);
listView.addHeaderView(view1);
@@ -70,7 +71,7 @@ public class ShadowListViewTest {
@Test
public void addHeaderView_shouldAttachTheViewToTheList() throws Exception {
- View view = new View(RuntimeEnvironment.application);
+ View view = new View((Application) ApplicationProvider.getApplicationContext());
view.setId(42);
listView.addHeaderView(view);
@@ -80,8 +81,8 @@ public class ShadowListViewTest {
@Test
public void addFooterView_ShouldRecordFooters() throws Exception {
- View view0 = new View(RuntimeEnvironment.application);
- View view1 = new View(RuntimeEnvironment.application);
+ View view0 = new View((Application) ApplicationProvider.getApplicationContext());
+ View view1 = new View((Application) ApplicationProvider.getApplicationContext());
listView.addFooterView(view0);
listView.addFooterView(view1);
listView.setAdapter(new ShadowCountingAdapter(3));
@@ -91,7 +92,7 @@ public class ShadowListViewTest {
@Test
public void addFooterView_shouldAttachTheViewToTheList() throws Exception {
- View view = new View(RuntimeEnvironment.application);
+ View view = new View((Application) ApplicationProvider.getApplicationContext());
view.setId(42);
listView.addFooterView(view);
@@ -101,9 +102,9 @@ public class ShadowListViewTest {
@Test
public void setAdapter_shouldNotClearHeaderOrFooterViews() throws Exception {
- View header = new View(RuntimeEnvironment.application);
+ View header = new View((Application) ApplicationProvider.getApplicationContext());
listView.addHeaderView(header);
- View footer = new View(RuntimeEnvironment.application);
+ View footer = new View((Application) ApplicationProvider.getApplicationContext());
listView.addFooterView(footer);
prepareListWithThreeItems();
@@ -115,9 +116,9 @@ public class ShadowListViewTest {
@Test
public void testGetFooterViewsCount() throws Exception {
- listView.addHeaderView(new View(RuntimeEnvironment.application));
- listView.addFooterView(new View(RuntimeEnvironment.application));
- listView.addFooterView(new View(RuntimeEnvironment.application));
+ listView.addHeaderView(new View((Application) ApplicationProvider.getApplicationContext()));
+ listView.addFooterView(new View((Application) ApplicationProvider.getApplicationContext()));
+ listView.addFooterView(new View((Application) ApplicationProvider.getApplicationContext()));
prepareListWithThreeItems();
@@ -208,7 +209,7 @@ public class ShadowListViewTest {
@Test(expected = UnsupportedOperationException.class)
public void removeView_shouldThrowAnException() throws Exception {
- listView.removeView(new View(RuntimeEnvironment.application));
+ listView.removeView(new View((Application) ApplicationProvider.getApplicationContext()));
}
@Test(expected = UnsupportedOperationException.class)
@@ -226,7 +227,7 @@ public class ShadowListViewTest {
@Test
public void getPositionForView_shouldReturnInvalidPositionForViewThatIsNotFound() throws Exception {
prepareWithListAdapter();
- View view = new View(RuntimeEnvironment.application);
+ View view = new View((Application) ApplicationProvider.getApplicationContext());
shadowOf(view).setMyParent(ReflectionHelpers.createNullProxy(ViewParent.class)); // Android implementation requires the item have a parent
assertThat(listView.getPositionForView(view)).isEqualTo(AdapterView.INVALID_POSITION);
}
@@ -384,8 +385,9 @@ public class ShadowListViewTest {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- LinearLayout linearLayout = new LinearLayout(RuntimeEnvironment.application);
- linearLayout.addView(new View(RuntimeEnvironment.application));
+ LinearLayout linearLayout =
+ new LinearLayout((Application) ApplicationProvider.getApplicationContext());
+ linearLayout.addView(new View((Application) ApplicationProvider.getApplicationContext()));
return linearLayout;
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowLocaleDataTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowLocaleDataTest.java
index 88e36fab1..7df2e9018 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowLocaleDataTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowLocaleDataTest.java
@@ -7,15 +7,15 @@ import static android.os.Build.VERSION_CODES.M;
import static com.google.common.truth.Truth.assertThat;
import android.os.Build;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Locale;
import libcore.icu.LocaleData;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowLocaleDataTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowLocationManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowLocationManagerTest.java
index 87b57498a..358cbf389 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowLocationManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowLocationManagerTest.java
@@ -10,6 +10,7 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
@@ -21,6 +22,8 @@ import android.location.LocationManager;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Process;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -31,18 +34,19 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowLocationManagerTest {
private LocationManager locationManager;
private ShadowLocationManager shadowLocationManager;
@Before
public void setUp() {
- locationManager = (LocationManager) RuntimeEnvironment.application.getSystemService(Context.LOCATION_SERVICE);
+ locationManager =
+ (LocationManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.LOCATION_SERVICE);
shadowLocationManager = shadowOf(locationManager);
}
@@ -190,12 +194,19 @@ public class ShadowLocationManagerTest {
@Test
public void shouldRemovePendingIntentsWhenRequestingLocationUpdatesUsingCriteria() throws Exception {
Intent someIntent = new Intent("some_action");
- PendingIntent someLocationListenerPendingIntent = PendingIntent.getBroadcast(RuntimeEnvironment.application, 0, someIntent,
- PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent someLocationListenerPendingIntent =
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(),
+ 0,
+ someIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
Intent someOtherIntent = new Intent("some_other_action");
- PendingIntent someOtherLocationListenerPendingIntent = PendingIntent.getBroadcast(
- RuntimeEnvironment.application, 0, someOtherIntent,
- PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent someOtherLocationListenerPendingIntent =
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(),
+ 0,
+ someOtherIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
shadowLocationManager.setProviderEnabled(GPS_PROVIDER, true);
shadowLocationManager.setBestProvider(LocationManager.GPS_PROVIDER, true);
@@ -227,11 +238,19 @@ public class ShadowLocationManagerTest {
@Test
public void shouldRemovePendingIntentsWhenRequestingLocationUpdatesUsingLocationListeners() throws Exception {
Intent someIntent = new Intent("some_action");
- PendingIntent someLocationListenerPendingIntent = PendingIntent.getBroadcast(RuntimeEnvironment.application, 0,
- someIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent someLocationListenerPendingIntent =
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(),
+ 0,
+ someIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
Intent someOtherIntent = new Intent("some_other_action");
- PendingIntent someOtherLocationListenerPendingIntent = PendingIntent.getBroadcast(RuntimeEnvironment.application,
- 0, someOtherIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent someOtherLocationListenerPendingIntent =
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(),
+ 0,
+ someOtherIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
shadowLocationManager.setProviderEnabled(GPS_PROVIDER, true);
shadowLocationManager.setBestProvider(LocationManager.GPS_PROVIDER, true);
@@ -278,8 +297,12 @@ public class ShadowLocationManagerTest {
@Test
public void shouldThrowExceptionWhenRequestingLocationUpdatesAndNoProviderIsFound() throws Exception {
Intent someIntent = new Intent("some_action");
- PendingIntent someLocationListenerPendingIntent = PendingIntent.getBroadcast(RuntimeEnvironment.application, 0,
- someIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent someLocationListenerPendingIntent =
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(),
+ 0,
+ someIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
try {
@@ -376,8 +399,12 @@ public class ShadowLocationManagerTest {
shadowLocationManager.setBestProvider(LocationManager.GPS_PROVIDER, true);
Intent someIntent = new Intent("some_action");
- PendingIntent someLocationListenerPendingIntent = PendingIntent.getBroadcast(RuntimeEnvironment.application, 0,
- someIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent someLocationListenerPendingIntent =
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(),
+ 0,
+ someIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
locationManager.requestLocationUpdates(GPS_PROVIDER, 0, 0, someLocationListenerPendingIntent);
assertThat(shadowLocationManager.getRequestLocationUdpateProviderPendingIntents().get(someLocationListenerPendingIntent)).isEqualTo(GPS_PROVIDER);
@@ -391,8 +418,12 @@ public class ShadowLocationManagerTest {
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
Intent someIntent = new Intent("some_action");
- PendingIntent someLocationListenerPendingIntent = PendingIntent.getBroadcast(RuntimeEnvironment.application, 0,
- someIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent someLocationListenerPendingIntent =
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(),
+ 0,
+ someIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
Criteria someCriteria = new Criteria();
someCriteria.setAccuracy(Criteria.ACCURACY_COARSE);
locationManager.requestLocationUpdates(0, 0, someCriteria, someLocationListenerPendingIntent);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowLogTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowLogTest.java
index 7639e6116..ace202301 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowLogTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowLogTest.java
@@ -8,16 +8,16 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.util.Log;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.Iterables;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowLog.LogItem;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowLogTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowLooperTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowLooperTest.java
index 015c7532c..11d997891 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowLooperTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowLooperTest.java
@@ -8,6 +8,8 @@ import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
@@ -17,12 +19,11 @@ import org.junit.Test;
import org.junit.rules.TestName;
import org.junit.runner.RunWith;
import org.robolectric.RoboSettings;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.Scheduler;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowLooperTest {
// testName is used when creating background threads. Makes it
@@ -45,11 +46,11 @@ public class ShadowLooperTest {
private boolean hasContinued = false;
private Looper looper;
private CountDownLatch started = new CountDownLatch(1);
-
+
public QuitThread() {
super(testName.getMethodName());
}
-
+
@Override
public void run() {
Looper.prepare();
@@ -59,14 +60,14 @@ public class ShadowLooperTest {
hasContinued = true;
}
}
-
+
private QuitThread getQuitThread() throws InterruptedException {
QuitThread qt = new QuitThread();
qt.start();
qt.started.await();
return qt;
}
-
+
@Test
public void mainLooper_andMyLooper_shouldBeSame_onMainThread() {
assertThat(Looper.myLooper()).isSameAs(Looper.getMainLooper());
@@ -87,18 +88,18 @@ public class ShadowLooperTest {
public void shadowMainLooper_shouldBeShadowOfMainLooper() {
assertThat(ShadowLooper.getShadowMainLooper()).isSameAs(shadowOf(Looper.getMainLooper()));
}
-
+
@Test
public void getLooperForThread_returnsLooperForAThreadThatHasOne() throws InterruptedException {
QuitThread qt = getQuitThread();
assertThat(ShadowLooper.getLooperForThread(qt)).isSameAs(qt.looper);
}
-
+
@Test
public void getLooperForThread_returnsLooperForMainThread() {
assertThat(ShadowLooper.getLooperForThread(Thread.currentThread())).isSameAs(Looper.getMainLooper());
}
-
+
@Test
public void idleMainLooper_executesScheduledTasks() {
final boolean[] wasRun = new boolean[]{false};
@@ -216,12 +217,12 @@ public class ShadowLooperTest {
test.join(5000);
assertThat(test.hasContinued).named("hasContinued:after").isTrue();
}
-
+
@Test(timeout = 1000)
public void whenTestHarnessUsesDifferentThread_shouldStillHaveMainLooper() {
assertThat(Looper.myLooper()).isSameAs(Looper.getMainLooper());
}
-
+
@Test
public void resetThreadLoopers_fromNonMainThread_shouldThrowISE() throws InterruptedException {
final AtomicReference<Throwable> ex = new AtomicReference<>();
@@ -239,18 +240,23 @@ public class ShadowLooperTest {
t.join();
assertThat(ex.get()).isInstanceOf(IllegalStateException.class);
}
-
+
@Test
public void soStaticRefsToLoopersInAppWorksAcrossTests_shouldRetainSameLooperForMainThreadBetweenResetsButGiveItAFreshScheduler() throws Exception {
Looper mainLooper = Looper.getMainLooper();
Scheduler scheduler = shadowOf(mainLooper).getScheduler();
shadowOf(mainLooper).quit = true;
- assertThat(RuntimeEnvironment.application.getMainLooper()).isSameAs(mainLooper);
+ assertThat(ApplicationProvider.getApplicationContext().getMainLooper()).isSameAs(mainLooper);
Scheduler s = new Scheduler();
RuntimeEnvironment.setMasterScheduler(s);
ShadowLooper.resetThreadLoopers();
Application application = new Application();
- ReflectionHelpers.callInstanceMethod(application, "attach", ReflectionHelpers.ClassParameter.from(Context.class, RuntimeEnvironment.application.getBaseContext()));
+ ReflectionHelpers.callInstanceMethod(
+ application,
+ "attach",
+ ReflectionHelpers.ClassParameter.from(
+ Context.class,
+ ((Application) ApplicationProvider.getApplicationContext()).getBaseContext()));
assertThat(Looper.getMainLooper()).named("Looper.getMainLooper()").isSameAs(mainLooper);
assertThat(application.getMainLooper()).named("app.getMainLooper()").isSameAs(mainLooper);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowLruTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowLruTest.java
index 81182a41a..cecf93e09 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowLruTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowLruTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.util.LruCache;
+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 ShadowLruTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMarginLayoutParamsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMarginLayoutParamsTest.java
index ca9c322fd..e9aedf4b5 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMarginLayoutParamsTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMarginLayoutParamsTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.view.ViewGroup;
+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 ShadowMarginLayoutParamsTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMatrixCursorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMatrixCursorTest.java
index 248f8415c..d38d7825e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMatrixCursorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMatrixCursorTest.java
@@ -6,13 +6,13 @@ import static org.junit.Assert.assertTrue;
import android.database.CursorIndexOutOfBoundsException;
import android.database.MatrixCursor;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Arrays;
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 ShadowMatrixCursorTest {
private MatrixCursor singleColumnSingleNullValueMatrixCursor;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMatrixTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMatrixTest.java
index 892c2c84f..9ac75226c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMatrixTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMatrixTest.java
@@ -7,12 +7,12 @@ import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Build;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowMatrixTest {
private static final float EPSILON = 1e-7f;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaMetadataRetrieverTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaMetadataRetrieverTest.java
index c590b5d3d..b9e85e007 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaMetadataRetrieverTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaMetadataRetrieverTest.java
@@ -10,19 +10,20 @@ import static org.robolectric.shadows.ShadowMediaMetadataRetriever.addFrame;
import static org.robolectric.shadows.ShadowMediaMetadataRetriever.addMetadata;
import static org.robolectric.shadows.util.DataSource.toDataSource;
+import android.app.Application;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.FileDescriptor;
import java.util.HashMap;
import java.util.Map;
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 ShadowMediaMetadataRetrieverTest {
private final String path = "/media/foo.mp3";
private final String path2 = "/media/foo2.mp3";
@@ -78,7 +79,7 @@ public class ShadowMediaMetadataRetrieverTest {
@Test
public void getFrameAtTime_shouldDependOnTime() {
- Context context = RuntimeEnvironment.application;
+ Context context = (Application) ApplicationProvider.getApplicationContext();
Uri uri = Uri.parse(path);
addFrame(context, uri, 12, bitmap);
addFrame(context, uri, 13, bitmap2);
@@ -91,7 +92,7 @@ public class ShadowMediaMetadataRetrieverTest {
@Test
public void setDataSource_ignoresHeadersWhenShadowed() {
- Context context = RuntimeEnvironment.application;
+ Context context = (Application) ApplicationProvider.getApplicationContext();
Uri uri = Uri.parse(path);
Map<String, String> headers = new HashMap<>();
headers.put("cookie", "nomnomnom");
@@ -126,7 +127,7 @@ public class ShadowMediaMetadataRetrieverTest {
throw new RuntimeException("Shouldn't throw exception after reset", e);
}
}
-
+
@Test
public void setDataSourceException_withAllowedException() {
RuntimeException e = new RuntimeException("some dummy message");
@@ -137,8 +138,8 @@ public class ShadowMediaMetadataRetrieverTest {
} catch (Exception caught) {
assertThat(caught).isSameAs(e);
assertThat(e.getStackTrace()[0].getClassName())
- .named("Stack trace should originate in Shadow")
- .isEqualTo(ShadowMediaMetadataRetriever.class.getName());
+ .named("Stack trace should originate in Shadow")
+ .isEqualTo(ShadowMediaMetadataRetriever.class.getName());
}
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaPlayerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaPlayerTest.java
index 105239099..a741a2689 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaPlayerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaPlayerTest.java
@@ -17,10 +17,13 @@ import static org.robolectric.shadows.ShadowMediaPlayer.State.STOPPED;
import static org.robolectric.shadows.ShadowMediaPlayer.addException;
import static org.robolectric.shadows.util.DataSource.toDataSource;
+import android.app.Application;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Looper;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -38,8 +41,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowMediaPlayer.InvalidStateBehavior;
@@ -50,7 +51,7 @@ import org.robolectric.shadows.util.DataSource;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.Scheduler;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowMediaPlayerTest {
private static final String DUMMY_SOURCE = "dummy-source";
@@ -101,15 +102,20 @@ public class ShadowMediaPlayerTest {
public void create_withResourceId_shouldSetDataSource() {
ShadowMediaPlayer.addMediaInfo(
DataSource.toDataSource(
- "android.resource://" + RuntimeEnvironment.application.getPackageName() + "/123"),
+ "android.resource://"
+ + ((Application) ApplicationProvider.getApplicationContext()).getPackageName()
+ + "/123"),
new ShadowMediaPlayer.MediaInfo(100, 10));
- MediaPlayer mp = MediaPlayer.create(RuntimeEnvironment.application, 123);
+ MediaPlayer mp =
+ MediaPlayer.create((Application) ApplicationProvider.getApplicationContext(), 123);
ShadowMediaPlayer shadow = shadowOf(mp);
assertThat(shadow.getDataSource())
.isEqualTo(
DataSource.toDataSource(
- "android.resource://" + RuntimeEnvironment.application.getPackageName() + "/123"));
+ "android.resource://"
+ + ((Application) ApplicationProvider.getApplicationContext()).getPackageName()
+ + "/123"));
}
@Test
@@ -164,10 +170,12 @@ public class ShadowMediaPlayerTest {
public void testSetDataSourceUri() throws IOException {
Map<String, String> headers = new HashMap<>();
Uri uri = Uri.parse("file:/test");
- DataSource ds = toDataSource(RuntimeEnvironment.application, uri, headers);
+ DataSource ds =
+ toDataSource((Application) ApplicationProvider.getApplicationContext(), uri, headers);
ShadowMediaPlayer.addMediaInfo(ds, info);
- mediaPlayer.setDataSource(RuntimeEnvironment.application, uri, headers);
+ mediaPlayer.setDataSource(
+ (Application) ApplicationProvider.getApplicationContext(), uri, headers);
assertThat(shadowMediaPlayer.getSourceUri()).named("sourceUri").isSameAs(uri);
assertThat(shadowMediaPlayer.getDataSource()).named("dataSource").isEqualTo(ds);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaRecorderTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaRecorderTest.java
index cbba30a5a..85b02fa61 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaRecorderTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaRecorderTest.java
@@ -5,14 +5,14 @@ import static com.google.common.truth.Truth.assertThat;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.view.Surface;
+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.Shadows;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowMediaRecorderTest {
private MediaRecorder mediaRecorder;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaRouterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaRouterTest.java
index 71dec9ebd..3a81bd151 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaRouterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaRouterTest.java
@@ -8,25 +8,29 @@ import static android.os.Build.VERSION_CODES.N;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.media.MediaRouter;
import android.media.MediaRouter.RouteInfo;
+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;
import org.robolectric.annotation.Config;
/** Tests for {@link ShadowMediaRouter}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public final class ShadowMediaRouterTest {
private MediaRouter mediaRouter;
@Before
public void setUp() throws Exception {
mediaRouter =
- (MediaRouter) RuntimeEnvironment.application.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ (MediaRouter)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.MEDIA_ROUTER_SERVICE);
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaSessionTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaSessionTest.java
new file mode 100644
index 000000000..6c86aa040
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaSessionTest.java
@@ -0,0 +1,21 @@
+package org.robolectric.shadows;
+
+import android.app.Application;
+import android.media.session.MediaSession;
+import android.os.Build;
+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.annotation.Config;
+
+/** Tests for robolectric functionality around {@link MediaSession}. */
+@RunWith(AndroidJUnit4.class)
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+public class ShadowMediaSessionTest {
+ @Test
+ public void mediaSessionCompat_creation() throws Exception {
+ // Should not result in an exception.
+ new MediaSession((Application) ApplicationProvider.getApplicationContext(), "test");
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaStoreTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaStoreTest.java
index bc0726531..1196fbfb2 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaStoreTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaStoreTest.java
@@ -4,11 +4,11 @@ import static android.provider.MediaStore.Images;
import static android.provider.MediaStore.Video;
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 ShadowMediaStoreTest {
@Test
public void shouldInitializeFields() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMergeCursorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMergeCursorTest.java
index 7680d5f1b..49510b2fe 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMergeCursorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMergeCursorTest.java
@@ -6,12 +6,12 @@ import android.database.Cursor;
import android.database.MergeCursor;
import android.database.sqlite.SQLiteCursor;
import android.database.sqlite.SQLiteDatabase;
+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 ShadowMergeCursorTest {
private SQLiteDatabase database;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMessageQueueTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMessageQueueTest.java
index 492f238c2..98d7597d2 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMessageQueueTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMessageQueueTest.java
@@ -16,18 +16,18 @@ import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.os.SystemClock;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
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;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.Scheduler;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowMessageQueueTest {
private Looper looper;
private MessageQueue queue;
@@ -36,34 +36,34 @@ public class ShadowMessageQueueTest {
private TestHandler handler;
private Scheduler scheduler;
private String quitField;
-
+
private static class TestHandler extends Handler {
public List<Message> handled = new ArrayList<>();
-
+
public TestHandler(Looper looper) {
super(looper);
}
-
+
@Override
public void handleMessage(Message msg) {
handled.add(msg);
}
}
-
+
private static Looper newLooper() {
return newLooper(true);
}
-
+
private static Looper newLooper(boolean canQuit) {
return callConstructor(Looper.class, from(boolean.class, canQuit));
}
-
+
@Before
public void setUp() throws Exception {
// Queues and loopers are closely linked; can't easily test one without the other.
looper = newLooper();
handler = new TestHandler(looper);
- queue = looper.getQueue();
+ queue = looper.getQueue();
shadowQueue = shadowOf(queue);
scheduler = shadowQueue.getScheduler();
scheduler.pause();
@@ -81,7 +81,7 @@ public class ShadowMessageQueueTest {
return callInstanceMethod(queue, "enqueueMessage",
from(Message.class, msg),
from(long.class, when)
- );
+ );
}
private void removeMessages(Handler handler, int what, Object token) {
@@ -91,7 +91,7 @@ public class ShadowMessageQueueTest {
from(Object.class, token)
);
}
-
+
@Test
public void enqueueMessage_setsHead() {
enqueueMessage(testMessage, 100);
@@ -108,7 +108,7 @@ public class ShadowMessageQueueTest {
enqueueMessage(testMessage, 123);
assertThat(testMessage.getWhen()).named("when").isEqualTo(123);
}
-
+
@Test
public void enqueueMessage_returnsFalse_whenQuitting() {
setField(queue, quitField, true);
@@ -121,7 +121,7 @@ public class ShadowMessageQueueTest {
enqueueMessage(testMessage, 1);
assertThat(scheduler.size()).named("scheduler_size").isEqualTo(0);
}
-
+
@Test
public void enqueuedMessage_isSentToHandler() {
enqueueMessage(testMessage, 200);
@@ -130,7 +130,7 @@ public class ShadowMessageQueueTest {
scheduler.advanceTo(200);
assertThat(handler.handled).named("handled:after").containsExactly(testMessage);
}
-
+
@Test
public void removedMessage_isNotSentToHandler() {
enqueueMessage(testMessage, 200);
@@ -149,7 +149,7 @@ public class ShadowMessageQueueTest {
scheduler.advanceToLastPostedRunnable();
assertThat(handler.handled).named("handled").containsExactly(m2, testMessage);
}
-
+
@Test
public void dispatchedMessage_isMarkedInUse_andRecycled() {
Handler handler = new Handler(looper) {
@@ -166,16 +166,16 @@ public class ShadowMessageQueueTest {
Message msg2 = handler.obtainMessage(2);
enqueueMessage(msg2, 205);
scheduler.advanceToNextPostedRunnable();
-
+
// Check that it's been properly recycled.
assertThat(msg.what).named("msg.what").isEqualTo(0);
-
+
scheduler.advanceToNextPostedRunnable();
assertThat(msg2.what).named("msg2.what").isEqualTo(0);
}
-
- @Test
+
+ @Test
public void reset_shouldClearMessageQueue() {
Message msg = handler.obtainMessage(1234);
Message msg2 = handler.obtainMessage(5678);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMessageTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMessageTest.java
index 8d647c154..8699bd549 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMessageTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMessageTest.java
@@ -8,15 +8,15 @@ import static org.robolectric.Shadows.shadowOf;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.Scheduler;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowMessageTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMessengerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMessengerTest.java
index dbf5c722e..7d1a64c7b 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMessengerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMessengerTest.java
@@ -5,11 +5,11 @@ import static com.google.common.truth.Truth.assertThat;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
+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 ShadowMessengerTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMimeTypeMapTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMimeTypeMapTest.java
index 61bc58e5f..7e4060b58 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMimeTypeMapTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMimeTypeMapTest.java
@@ -8,12 +8,12 @@ import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
import android.webkit.MimeTypeMap;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowMimeTypeMapTest {
private static final String IMAGE_EXTENSION = "jpg";
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMotionEventTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMotionEventTest.java
index 33d21b70a..03c8afb60 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMotionEventTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMotionEventTest.java
@@ -5,12 +5,12 @@ import static org.junit.Assert.assertEquals;
import static org.robolectric.Shadows.shadowOf;
import android.view.MotionEvent;
+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 ShadowMotionEventTest {
private MotionEvent event;
private ShadowMotionEvent shadowMotionEvent;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkInfoTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkInfoTest.java
index 6e46c336b..6b23f09d6 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkInfoTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkInfoTest.java
@@ -4,12 +4,12 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.net.NetworkInfo;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowNetworkInfoTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkScoreManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkScoreManagerTest.java
index 81a11439a..915a024e0 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkScoreManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkScoreManagerTest.java
@@ -3,16 +3,17 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.content.Context;
import android.net.NetworkScoreManager;
+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;
import org.robolectric.annotation.Config;
/** ShadowNetworkScoreManagerTest tests {@link ShadowNetworkScoreManager}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public final class ShadowNetworkScoreManagerTest {
@Test
@@ -20,7 +21,8 @@ public final class ShadowNetworkScoreManagerTest {
public void testGetActiveScorerPackage() throws Exception {
NetworkScoreManager networkScoreManager =
(NetworkScoreManager)
- RuntimeEnvironment.application.getSystemService(Context.NETWORK_SCORE_SERVICE);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.NETWORK_SCORE_SERVICE);
String testPackage = "com.package.test";
networkScoreManager.setActiveScorer(testPackage);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkTest.java
index 0afaed41f..bc5a473a9 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowNetworkTest.java
@@ -6,16 +6,16 @@ import static android.os.Build.VERSION_CODES.M;
import static com.google.common.truth.Truth.assertThat;
import android.net.Network;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.FileDescriptor;
import java.net.DatagramSocket;
import java.net.Socket;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowNetworkTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowNfcAdapterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowNfcAdapterTest.java
index 5f881de9e..5d24cea9b 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowNfcAdapterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowNfcAdapterTest.java
@@ -5,18 +5,19 @@ import static org.mockito.Mockito.mock;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
+import android.app.Application;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowNfcAdapterTest {
@Rule public ExpectedException expectedException = ExpectedException.none();
@@ -71,7 +72,8 @@ public class ShadowNfcAdapterTest {
@Test
public void isEnabled_shouldReturnEnabledState() {
- final NfcAdapter adapter = NfcAdapter.getDefaultAdapter(RuntimeEnvironment.application);
+ final NfcAdapter adapter =
+ NfcAdapter.getDefaultAdapter((Application) ApplicationProvider.getApplicationContext());
assertThat(adapter.isEnabled()).isFalse();
shadowOf(adapter).setEnabled(true);
@@ -83,21 +85,24 @@ public class ShadowNfcAdapterTest {
@Test
public void getNfcAdapter_returnsNonNull() {
- NfcAdapter adapter = NfcAdapter.getDefaultAdapter(RuntimeEnvironment.application);
+ NfcAdapter adapter =
+ NfcAdapter.getDefaultAdapter((Application) ApplicationProvider.getApplicationContext());
assertThat(adapter).isNotNull();
}
@Test
public void getNfcAdapter_hardwareExists_returnsNonNull() {
ShadowNfcAdapter.setNfcHardwareExists(true);
- NfcAdapter adapter = NfcAdapter.getDefaultAdapter(RuntimeEnvironment.application);
+ NfcAdapter adapter =
+ NfcAdapter.getDefaultAdapter((Application) ApplicationProvider.getApplicationContext());
assertThat(adapter).isNotNull();
}
@Test
public void getNfcAdapter_hardwareDoesNotExist_returnsNull() {
ShadowNfcAdapter.setNfcHardwareExists(false);
- NfcAdapter adapter = NfcAdapter.getDefaultAdapter(RuntimeEnvironment.application);
+ NfcAdapter adapter =
+ NfcAdapter.getDefaultAdapter((Application) ApplicationProvider.getApplicationContext());
assertThat(adapter).isNull();
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationBuilder25Test.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationBuilder25Test.java
index 6e023b483..d43b0c173 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationBuilder25Test.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationBuilder25Test.java
@@ -1,12 +1,13 @@
package org.robolectric.shadows;
+import android.app.Application;
import android.os.Build;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowNotificationBuilder25Test extends ShadowNotificationBuilderTest {
/**
@@ -15,7 +16,12 @@ public class ShadowNotificationBuilder25Test extends ShadowNotificationBuilderTe
*/
@Before
public void setup() throws Exception {
- RuntimeEnvironment.application.getPackageManager().getPackageInfo("org.robolectric", 0).applicationInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1;
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getPackageManager()
+ .getPackageInfo("org.robolectric", 0)
+ .applicationInfo
+ .targetSdkVersion =
+ Build.VERSION_CODES.N_MR1;
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationBuilderTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationBuilderTest.java
index 01eaed708..2f231a576 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationBuilderTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationBuilderTest.java
@@ -7,22 +7,24 @@ import static android.os.Build.VERSION_CODES.N;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.Notification;
import android.app.PendingIntent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Icon;
import android.text.SpannableString;
+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.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowNotificationBuilderTest {
- private final Notification.Builder builder = new Notification.Builder(RuntimeEnvironment.application);
+ private final Notification.Builder builder =
+ new Notification.Builder((Application) ApplicationProvider.getApplicationContext());
@Test
public void build_setsContentTitleOnNotification() throws Exception {
@@ -210,7 +212,9 @@ public class ShadowNotificationBuilderTest {
@Test
@Config(minSdk = JELLY_BEAN_MR2)
public void build_addsActionToNotification() throws Exception {
- PendingIntent action = PendingIntent.getBroadcast(RuntimeEnvironment.application, 0, null, 0);
+ PendingIntent action =
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(), 0, null, 0);
Notification notification = builder.addAction(0, "Action", action).build();
assertThat(notification.actions[0].actionIntent).isEqualTo(action);
@@ -233,7 +237,10 @@ public class ShadowNotificationBuilderTest {
@Test
@Config(minSdk = M)
public void withBigPictureStyle() {
- Bitmap bigPicture = BitmapFactory.decodeResource(RuntimeEnvironment.application.getResources(), R.drawable.an_image);
+ Bitmap bigPicture =
+ BitmapFactory.decodeResource(
+ ((Application) ApplicationProvider.getApplicationContext()).getResources(),
+ R.drawable.an_image);
Icon bigLargeIcon = Icon.createWithBitmap(bigPicture);
Notification notification = builder.setStyle(new Notification.BigPictureStyle(builder)
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationManagerTest.java
index ec98f5d1f..26bf9e6fb 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationManagerTest.java
@@ -8,6 +8,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.AutomaticZenRule;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -19,24 +20,27 @@ import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.service.notification.StatusBarNotification;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowNotificationManagerTest {
private NotificationManager notificationManager;
private Notification notification1 = new Notification();
private Notification notification2 = new Notification();
@Before public void setUp() {
- notificationManager = (NotificationManager) RuntimeEnvironment.application.getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager =
+ (NotificationManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.NOTIFICATION_SERVICE);
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationTest.java
index ae3b673ee..e7e51163e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowNotificationTest.java
@@ -6,11 +6,11 @@ import static org.robolectric.RuntimeEnvironment.application;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
+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 ShadowNotificationTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowNumberPickerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowNumberPickerTest.java
index 7eb996a55..9044a0dd9 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowNumberPickerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowNumberPickerTest.java
@@ -3,19 +3,21 @@ package org.robolectric.shadows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import android.app.Application;
import android.widget.NumberPicker;
+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;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowNumberPickerTest {
@Test
public void shouldFireListeners() {
- NumberPicker picker = new NumberPicker(RuntimeEnvironment.application);
+ NumberPicker picker =
+ new NumberPicker((Application) ApplicationProvider.getApplicationContext());
NumberPicker.OnValueChangeListener listener = mock(NumberPicker.OnValueChangeListener.class);
picker.setOnValueChangedListener(listener);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowObjectAnimatorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowObjectAnimatorTest.java
index 89720f107..736f73352 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowObjectAnimatorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowObjectAnimatorTest.java
@@ -4,14 +4,14 @@ import static com.google.common.truth.Truth.assertThat;
import android.animation.Animator;
import android.animation.ObjectAnimator;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowObjectAnimatorTest {
private final AnimatorTarget target = new AnimatorTarget();
private List<String> listenerEvents = new ArrayList<>();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowOpenGLMatrixTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowOpenGLMatrixTest.java
index cce37507a..c4429fb89 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowOpenGLMatrixTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowOpenGLMatrixTest.java
@@ -5,12 +5,12 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static com.google.common.truth.Truth.assertThat;
import android.opengl.Matrix;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowOpenGLMatrixTest {
@Test(expected = IllegalArgumentException.class)
public void multiplyMM_failIfResIsNull() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowOutlineTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowOutlineTest.java
index 045141725..7870d7ca2 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowOutlineTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowOutlineTest.java
@@ -4,12 +4,12 @@ import static android.os.Build.VERSION_CODES.LOLLIPOP;
import android.graphics.Outline;
import android.graphics.Path;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowOutlineTest {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowOverScrollerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowOverScrollerTest.java
index 38e7d1e1e..b4c0724ba 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowOverScrollerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowOverScrollerTest.java
@@ -2,21 +2,24 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.view.animation.LinearInterpolator;
import android.widget.OverScroller;
+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 ShadowOverScrollerTest {
private OverScroller overScroller;
@Before
public void setUp() {
- overScroller = new OverScroller(RuntimeEnvironment.application, new LinearInterpolator());
+ overScroller =
+ new OverScroller(
+ (Application) ApplicationProvider.getApplicationContext(), new LinearInterpolator());
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPackageInstallerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPackageInstallerTest.java
index 7ccff19af..47bff61cf 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPackageInstallerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPackageInstallerTest.java
@@ -6,20 +6,21 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.IIntentSender;
import android.content.IntentSender;
import android.content.pm.PackageInstaller;
import android.os.Handler;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.OutputStream;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowPackageInstallerTest {
@@ -30,7 +31,10 @@ public class ShadowPackageInstallerTest {
@Before
public void setUp() {
- packageInstaller = RuntimeEnvironment.application.getPackageManager().getPackageInstaller();
+ packageInstaller =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getPackageManager()
+ .getPackageInstaller();
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPackageManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPackageManagerTest.java
index 327f3eedf..3be41a2ff 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPackageManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPackageManagerTest.java
@@ -33,9 +33,6 @@ import static android.os.Build.VERSION_CODES.N_MR1;
import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
@@ -81,6 +78,8 @@ import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.Process;
import android.provider.DocumentsContract;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import java.io.ByteArrayInputStream;
@@ -96,12 +95,10 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowPackageManager.PackageSetting;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowPackageManagerTest {
private static final String TEST_PACKAGE_NAME = "com.some.other.package";
@@ -119,14 +116,18 @@ public class ShadowPackageManagerTest {
@Before
public void setUp() {
- packageManager = RuntimeEnvironment.application.getPackageManager();
+ packageManager =
+ ApplicationProvider.getApplicationContext().getPackageManager();
shadowPackageManager = shadowOf(packageManager);
}
@Test
@Config(minSdk = LOLLIPOP)
public void packageInstallerCreateSession() throws Exception {
- PackageInstaller packageInstaller = RuntimeEnvironment.application.getPackageManager().getPackageInstaller();
+ PackageInstaller packageInstaller =
+ ApplicationProvider.getApplicationContext()
+ .getPackageManager()
+ .getPackageInstaller();
int sessionId = packageInstaller.createSession(createSessionParams("packageName"));
PackageInstaller.SessionInfo sessionInfo = packageInstaller.getSessionInfo(sessionId);
@@ -142,7 +143,10 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void packageInstallerOpenSession() throws Exception {
- PackageInstaller packageInstaller = RuntimeEnvironment.application.getPackageManager().getPackageInstaller();
+ PackageInstaller packageInstaller =
+ ApplicationProvider.getApplicationContext()
+ .getPackageManager()
+ .getPackageInstaller();
int sessionId = packageInstaller.createSession(createSessionParams("packageName"));
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
@@ -159,7 +163,7 @@ public class ShadowPackageManagerTest {
@Test
public void packageInstallerAndGetPackageArchiveInfo() {
ApplicationInfo appInfo = new ApplicationInfo();
- appInfo.flags = 0;
+ appInfo.flags = ApplicationInfo.FLAG_INSTALLED;
appInfo.packageName = TEST_PACKAGE_NAME;
appInfo.sourceDir = TEST_APP_PATH;
appInfo.name = TEST_PACKAGE_LABEL;
@@ -200,7 +204,8 @@ public class ShadowPackageManagerTest {
*/
@Test
public void testCheckPermission_thisPackage() throws Exception {
- String thisPackage = RuntimeEnvironment.application.getPackageName();
+ String thisPackage =
+ ApplicationProvider.getApplicationContext().getPackageName();
assertEquals(PERMISSION_GRANTED, packageManager.checkPermission(
"android.permission.INTERNET", thisPackage));
assertEquals(PERMISSION_GRANTED, packageManager.checkPermission(
@@ -340,7 +345,7 @@ public class ShadowPackageManagerTest {
@Test
public void testQueryBroadcastReceiverSucceeds() {
Intent intent = new Intent("org.robolectric.ACTION_RECEIVER_PERMISSION_PACKAGE");
- intent.setPackage(RuntimeEnvironment.application.getPackageName());
+ intent.setPackage(ApplicationProvider.getApplicationContext().getPackageName());
List<ResolveInfo> receiverInfos = packageManager.queryBroadcastReceivers(intent, PackageManager.GET_INTENT_FILTERS);
assertThat(receiverInfos).isNotEmpty();
@@ -356,13 +361,13 @@ public class ShadowPackageManagerTest {
public void testQueryBroadcastReceiverFailsForMissingPackageName() {
Intent intent = new Intent("org.robolectric.ACTION_ONE_MORE_PACKAGE");
List<ResolveInfo> receiverInfos = packageManager.queryBroadcastReceivers(intent, PackageManager.GET_INTENT_FILTERS);
- assertTrue(receiverInfos.size() == 0);
+ assertThat(receiverInfos).hasSize(0);
}
@Test
public void testQueryBroadcastReceiver_matchAllWithoutIntentFilter() {
Intent intent = new Intent();
- intent.setPackage(RuntimeEnvironment.application.getPackageName());
+ intent.setPackage(ApplicationProvider.getApplicationContext().getPackageName());
List<ResolveInfo> receiverInfos = packageManager.queryBroadcastReceivers(intent, PackageManager.GET_INTENT_FILTERS);
assertThat(receiverInfos).hasSize(7);
@@ -374,7 +379,10 @@ public class ShadowPackageManagerTest {
@Test
public void testGetPackageInfo_ForReceiversSucceeds() throws Exception {
- PackageInfo receiverInfos = packageManager.getPackageInfo(RuntimeEnvironment.application.getPackageName(), PackageManager.GET_RECEIVERS);
+ PackageInfo receiverInfos =
+ packageManager.getPackageInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ PackageManager.GET_RECEIVERS);
assertThat(receiverInfos.receivers).isNotEmpty();
assertThat(receiverInfos.receivers[0].name).isEqualTo("org.robolectric.ConfigTestReceiver.InnerReceiver");
@@ -433,7 +441,7 @@ public class ShadowPackageManagerTest {
@Test
public void getPermissionGroupInfo_fromManifest() throws Exception {
PermissionGroupInfo permissionGroupInfo =
- RuntimeEnvironment.application
+ ApplicationProvider.getApplicationContext()
.getPackageManager()
.getPermissionGroupInfo("org.robolectric.package_permission_group", 0);
assertThat(permissionGroupInfo.name).isEqualTo("org.robolectric.package_permission_group");
@@ -478,7 +486,7 @@ public class ShadowPackageManagerTest {
// Package 1
Package pkg = new Package(TEST_PACKAGE_NAME);
ApplicationInfo appInfo = pkg.applicationInfo;
- appInfo.flags = 0;
+ appInfo.flags = ApplicationInfo.FLAG_INSTALLED;
appInfo.packageName = TEST_PACKAGE_NAME;
appInfo.sourceDir = TEST_APP_PATH;
appInfo.name = TEST_PACKAGE_LABEL;
@@ -498,7 +506,7 @@ public class ShadowPackageManagerTest {
// Package 2, contains one permission group that is the same
Package pkg2 = new Package(TEST_PACKAGE2_NAME);
ApplicationInfo appInfo2 = pkg2.applicationInfo;
- appInfo2.flags = 0;
+ appInfo2.flags = ApplicationInfo.FLAG_INSTALLED;
appInfo2.packageName = TEST_PACKAGE2_NAME;
appInfo2.sourceDir = TEST_APP2_PATH;
appInfo2.name = TEST_PACKAGE2_LABEL;
@@ -524,7 +532,7 @@ public class ShadowPackageManagerTest {
@Test
public void getPackageArchiveInfo() {
ApplicationInfo appInfo = new ApplicationInfo();
- appInfo.flags = 0;
+ appInfo.flags = ApplicationInfo.FLAG_INSTALLED;
appInfo.packageName = TEST_PACKAGE_NAME;
appInfo.sourceDir = TEST_APP_PATH;
appInfo.name = TEST_PACKAGE_LABEL;
@@ -544,27 +552,39 @@ public class ShadowPackageManagerTest {
@Test
public void getApplicationInfo_ThisApplication() throws Exception {
- ApplicationInfo info = packageManager.getApplicationInfo(RuntimeEnvironment.application.getPackageName(), 0);
+ ApplicationInfo info =
+ packageManager.getApplicationInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(), 0);
assertThat(info).isNotNull();
- assertThat(info.packageName).isEqualTo(RuntimeEnvironment.application.getPackageName());
+ assertThat(info.packageName)
+ .isEqualTo(ApplicationProvider.getApplicationContext().getPackageName());
}
@Test
public void getApplicationInfo_uninstalledApplication_includeUninstalled() throws Exception {
packageManager.setApplicationEnabledSetting(
- RuntimeEnvironment.application.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, 0);
- ApplicationInfo info = packageManager.getApplicationInfo(RuntimeEnvironment.application.getPackageName(), MATCH_UNINSTALLED_PACKAGES);
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ COMPONENT_ENABLED_STATE_DISABLED,
+ 0);
+ ApplicationInfo info =
+ packageManager.getApplicationInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ MATCH_UNINSTALLED_PACKAGES);
assertThat(info).isNotNull();
- assertThat(info.packageName).isEqualTo(RuntimeEnvironment.application.getPackageName());
+ assertThat(info.packageName)
+ .isEqualTo(ApplicationProvider.getApplicationContext().getPackageName());
}
@Test
public void getApplicationInfo_uninstalledApplication_dontIncludeUninstalled() throws Exception {
packageManager.setApplicationEnabledSetting(
- RuntimeEnvironment.application.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, 0);
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ COMPONENT_ENABLED_STATE_DISABLED,
+ 0);
try {
- packageManager.getApplicationInfo(RuntimeEnvironment.application.getPackageName(), 0);
+ packageManager.getApplicationInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(), 0);
fail("PackageManager.NameNotFoundException not thrown");
} catch (PackageManager.NameNotFoundException e) {
// expected
@@ -574,11 +594,16 @@ public class ShadowPackageManagerTest {
@Test
public void getApplicationInfo_disabledApplication_includeDisabled() throws Exception {
packageManager.setApplicationEnabledSetting(
- RuntimeEnvironment.application.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, 0);
- ApplicationInfo info = packageManager.getApplicationInfo(
- RuntimeEnvironment.application.getPackageName(), MATCH_DISABLED_COMPONENTS);
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ COMPONENT_ENABLED_STATE_DISABLED,
+ 0);
+ ApplicationInfo info =
+ packageManager.getApplicationInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ MATCH_DISABLED_COMPONENTS);
assertThat(info).isNotNull();
- assertThat(info.packageName).isEqualTo(RuntimeEnvironment.application.getPackageName());
+ assertThat(info.packageName)
+ .isEqualTo(ApplicationProvider.getApplicationContext().getPackageName());
}
@Test(expected = PackageManager.NameNotFoundException.class)
@@ -654,6 +679,23 @@ public class ShadowPackageManagerTest {
}
@Test
+ public void queryIntentActivities_ServiceMatch() throws Exception {
+ Intent i = new Intent("SomeStrangeAction");
+
+ ResolveInfo info = new ResolveInfo();
+ info.nonLocalizedLabel = TEST_PACKAGE_LABEL;
+ info.serviceInfo = new ServiceInfo();
+ info.serviceInfo.name = "name";
+ info.serviceInfo.packageName = TEST_PACKAGE_NAME;
+
+ shadowPackageManager.addResolveInfoForIntent(i, info);
+
+ List<ResolveInfo> activities = packageManager.queryIntentActivities(i, 0);
+ assertThat(activities).isNotNull();
+ assertThat(activities).isEmpty();
+ }
+
+ @Test
@Config(minSdk = JELLY_BEAN_MR1)
public void queryIntentActivitiesAsUser_EmptyResult() throws Exception {
Intent i = new Intent(Intent.ACTION_APP_ERROR, null);
@@ -727,7 +769,9 @@ public class ShadowPackageManagerTest {
@Test
public void queryIntentActivities_MatchWithExplicitIntent() throws Exception {
Intent i = new Intent();
- i.setClassName(RuntimeEnvironment.application, "org.robolectric.shadows.TestActivity");
+ i.setClassName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.shadows.TestActivity");
List<ResolveInfo> activities = packageManager.queryIntentActivities(i, 0);
assertThat(activities).isNotNull();
@@ -768,10 +812,14 @@ public class ShadowPackageManagerTest {
@Test
public void queryIntentActivities_DisabledComponentExplicitIntent() throws Exception {
Intent i = new Intent();
- i.setClassName(RuntimeEnvironment.application, "org.robolectric.shadows.TestActivity");
+ i.setClassName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.shadows.TestActivity");
ComponentName componentToDisable =
- new ComponentName(RuntimeEnvironment.application, "org.robolectric.shadows.TestActivity");
+ new ComponentName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.shadows.TestActivity");
packageManager.setComponentEnabledSetting(
componentToDisable,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
@@ -789,7 +837,9 @@ public class ShadowPackageManagerTest {
i.setDataAndType(uri, "image/jpeg");
ComponentName componentToDisable =
- new ComponentName(RuntimeEnvironment.application, "org.robolectric.shadows.TestActivity");
+ new ComponentName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.shadows.TestActivity");
packageManager.setComponentEnabledSetting(
componentToDisable,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
@@ -807,7 +857,9 @@ public class ShadowPackageManagerTest {
i.setDataAndType(uri, "image/jpeg");
ComponentName componentToDisable =
- new ComponentName(RuntimeEnvironment.application, "org.robolectric.shadows.TestActivity");
+ new ComponentName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.shadows.TestActivity");
packageManager.setComponentEnabledSetting(
componentToDisable,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
@@ -822,12 +874,15 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void queryIntentActivities_appHidden_includeUninstalled() {
- String packageName = RuntimeEnvironment.application.getPackageName();
+ String packageName =
+ ApplicationProvider.getApplicationContext().getPackageName();
packageManager.setApplicationHiddenSettingAsUser(
packageName, /* hidden= */ true, /* user= */ null);
Intent i = new Intent();
- i.setClassName(RuntimeEnvironment.application, "org.robolectric.shadows.TestActivity");
+ i.setClassName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.shadows.TestActivity");
List<ResolveInfo> activities =
packageManager.queryIntentActivities(i, MATCH_UNINSTALLED_PACKAGES);
@@ -840,12 +895,15 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void queryIntentActivities_appHidden_dontIncludeUninstalled() {
- String packageName = RuntimeEnvironment.application.getPackageName();
+ String packageName =
+ ApplicationProvider.getApplicationContext().getPackageName();
packageManager.setApplicationHiddenSettingAsUser(
packageName, /* hidden= */ true, /* user= */ null);
Intent i = new Intent();
- i.setClassName(RuntimeEnvironment.application, "org.robolectric.shadows.TestActivity");
+ i.setClassName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.shadows.TestActivity");
assertThat(packageManager.queryIntentActivities(i, /* flags= */ 0)).isEmpty();
}
@@ -882,7 +940,7 @@ public class ShadowPackageManagerTest {
@Test
public void queryIntentServices_MatchWithExplicitIntent() throws Exception {
Intent i = new Intent();
- i.setClassName(RuntimeEnvironment.application, "com.foo.Service");
+ i.setClassName(ApplicationProvider.getApplicationContext(), "com.foo.Service");
List<ResolveInfo> services = packageManager.queryIntentServices(i, 0);
assertThat(services).isNotNull();
@@ -917,12 +975,13 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void queryIntentServices_appHidden_includeUninstalled() {
- String packageName = RuntimeEnvironment.application.getPackageName();
+ String packageName =
+ ApplicationProvider.getApplicationContext().getPackageName();
packageManager.setApplicationHiddenSettingAsUser(
packageName, /* hidden= */ true, /* user= */ null);
Intent i = new Intent();
- i.setClassName(RuntimeEnvironment.application, "com.foo.Service");
+ i.setClassName(ApplicationProvider.getApplicationContext(), "com.foo.Service");
List<ResolveInfo> services = packageManager.queryIntentServices(i, MATCH_UNINSTALLED_PACKAGES);
assertThat(services).hasSize(1);
@@ -933,12 +992,13 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void queryIntentServices_appHidden_dontIncludeUninstalled() {
- String packageName = RuntimeEnvironment.application.getPackageName();
+ String packageName =
+ ApplicationProvider.getApplicationContext().getPackageName();
packageManager.setApplicationHiddenSettingAsUser(
packageName, /* hidden= */ true, /* user= */ null);
Intent i = new Intent();
- i.setClassName(RuntimeEnvironment.application, "com.foo.Service");
+ i.setClassName(ApplicationProvider.getApplicationContext(), "com.foo.Service");
assertThat(packageManager.queryIntentServices(i, /* flags= */ 0)).isEmpty();
}
@@ -980,7 +1040,9 @@ public class ShadowPackageManagerTest {
@Test
public void queryBroadcastReceivers_MatchWithExplicitIntent() throws Exception {
Intent i = new Intent();
- i.setClassName(RuntimeEnvironment.application, "org.robolectric.fakes.ConfigTestReceiver");
+ i.setClassName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.fakes.ConfigTestReceiver");
List<ResolveInfo> receivers = packageManager.queryBroadcastReceivers(i, 0);
assertThat(receivers).isNotNull();
@@ -993,12 +1055,15 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void queryBroadcastReceivers_appHidden_includeUninstalled() {
- String packageName = RuntimeEnvironment.application.getPackageName();
+ String packageName =
+ ApplicationProvider.getApplicationContext().getPackageName();
packageManager.setApplicationHiddenSettingAsUser(
packageName, /* hidden= */ true, /* user= */ null);
Intent i = new Intent();
- i.setClassName(RuntimeEnvironment.application, "org.robolectric.fakes.ConfigTestReceiver");
+ i.setClassName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.fakes.ConfigTestReceiver");
List<ResolveInfo> activities =
packageManager.queryBroadcastReceivers(i, MATCH_UNINSTALLED_PACKAGES);
@@ -1011,12 +1076,15 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void queryBroadcastReceivers_appHidden_dontIncludeUninstalled() {
- String packageName = RuntimeEnvironment.application.getPackageName();
+ String packageName =
+ ApplicationProvider.getApplicationContext().getPackageName();
packageManager.setApplicationHiddenSettingAsUser(
packageName, /* hidden= */ true, /* user= */ null);
Intent i = new Intent();
- i.setClassName(RuntimeEnvironment.application, "org.robolectric.fakes.ConfigTestReceiver");
+ i.setClassName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.fakes.ConfigTestReceiver");
assertThat(packageManager.queryBroadcastReceivers(i, /* flags= */ 0)).isEmpty();
}
@@ -1106,12 +1174,15 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void queryIntentContentProviders_appHidden_includeUninstalled() {
- String packageName = RuntimeEnvironment.application.getPackageName();
+ String packageName =
+ ApplicationProvider.getApplicationContext().getPackageName();
packageManager.setApplicationHiddenSettingAsUser(
packageName, /* hidden= */ true, /* user= */ null);
Intent i = new Intent(DocumentsContract.PROVIDER_INTERFACE);
- i.setClassName(RuntimeEnvironment.application, "org.robolectric.shadows.TestActivity");
+ i.setClassName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.shadows.TestActivity");
ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.providerInfo = new ProviderInfo();
@@ -1225,7 +1296,8 @@ public class ShadowPackageManagerTest {
public void getPackageInfo_shouldReturnActivityInfos() throws Exception {
PackageInfo packageInfo =
packageManager.getPackageInfo(
- RuntimeEnvironment.application.getPackageName(), PackageManager.GET_ACTIVITIES);
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ PackageManager.GET_ACTIVITIES);
ActivityInfo activityInfoWithFilters =
findActivity(packageInfo.activities, ActivityWithFilters.class.getName());
assertThat(activityInfoWithFilters.packageName).isEqualTo("org.robolectric");
@@ -1244,7 +1316,10 @@ public class ShadowPackageManagerTest {
@Test
public void getPackageInfo_getProvidersShouldReturnProviderInfos() throws Exception {
- PackageInfo packageInfo = packageManager.getPackageInfo(RuntimeEnvironment.application.getPackageName(), PackageManager.GET_PROVIDERS);
+ PackageInfo packageInfo =
+ packageManager.getPackageInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ PackageManager.GET_PROVIDERS);
ProviderInfo[] providers = packageInfo.providers;
assertThat(providers).isNotEmpty();
assertThat(providers.length).isEqualTo(2);
@@ -1254,11 +1329,21 @@ public class ShadowPackageManagerTest {
@Test
public void getProviderInfo_shouldReturnProviderInfos() throws Exception {
- ProviderInfo providerInfo1 = packageManager.getProviderInfo(new ComponentName(RuntimeEnvironment.application, ".shadows.testing.TestContentProvider1"), 0);
+ ProviderInfo providerInfo1 =
+ packageManager.getProviderInfo(
+ new ComponentName(
+ ApplicationProvider.getApplicationContext(),
+ ".shadows.testing.TestContentProvider1"),
+ 0);
assertThat(providerInfo1.packageName).isEqualTo("org.robolectric");
assertThat(providerInfo1.authority).isEqualTo("org.robolectric.authority1");
- ProviderInfo providerInfo2 = packageManager.getProviderInfo(new ComponentName(RuntimeEnvironment.application, "org.robolectric.shadows.testing.TestContentProvider2"), 0);
+ ProviderInfo providerInfo2 =
+ packageManager.getProviderInfo(
+ new ComponentName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.shadows.testing.TestContentProvider2"),
+ 0);
assertThat(providerInfo2.packageName).isEqualTo("org.robolectric");
assertThat(providerInfo2.authority).isEqualTo("org.robolectric.authority2");
}
@@ -1275,7 +1360,12 @@ public class ShadowPackageManagerTest {
@Test
public void getProviderInfo_shouldPopulatePermissionsInProviderInfos() throws Exception {
- ProviderInfo providerInfo = packageManager.getProviderInfo(new ComponentName(RuntimeEnvironment.application, "org.robolectric.shadows.testing.TestContentProvider1"), 0);
+ ProviderInfo providerInfo =
+ packageManager.getProviderInfo(
+ new ComponentName(
+ ApplicationProvider.getApplicationContext(),
+ "org.robolectric.shadows.testing.TestContentProvider1"),
+ 0);
assertThat(providerInfo.authority).isEqualTo("org.robolectric.authority1");
assertThat(providerInfo.readPermission).isEqualTo("READ_PERMISSION");
@@ -1294,7 +1384,7 @@ public class ShadowPackageManagerTest {
ProviderInfo providerInfo =
packageManager.getProviderInfo(
new ComponentName(
- RuntimeEnvironment.application,
+ ApplicationProvider.getApplicationContext(),
"org.robolectric.shadows.testing.TestContentProvider1"),
PackageManager.GET_META_DATA);
assertThat(providerInfo.authority).isEqualTo("org.robolectric.authority1");
@@ -1311,7 +1401,12 @@ public class ShadowPackageManagerTest {
@Test
public void testReceiverInfo() throws Exception {
- ActivityInfo info = packageManager.getReceiverInfo(new ComponentName(RuntimeEnvironment.application, ".test.ConfigTestReceiver"), PackageManager.GET_META_DATA);
+ ActivityInfo info =
+ packageManager.getReceiverInfo(
+ new ComponentName(
+ ApplicationProvider.getApplicationContext(),
+ ".test.ConfigTestReceiver"),
+ PackageManager.GET_META_DATA);
assertThat(info.metaData.getInt("numberOfSheep")).isEqualTo(42);
}
@@ -1327,7 +1422,10 @@ public class ShadowPackageManagerTest {
@Test
public void getPackageInfo_shouldReturnRequestedPermissions() throws Exception {
- PackageInfo packageInfo = packageManager.getPackageInfo(RuntimeEnvironment.application.getPackageName(), PackageManager.GET_PERMISSIONS);
+ PackageInfo packageInfo =
+ packageManager.getPackageInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ PackageManager.GET_PERMISSIONS);
String[] permissions = packageInfo.requestedPermissions;
assertThat(permissions).isNotNull();
assertThat(permissions.length).isEqualTo(4);
@@ -1336,19 +1434,28 @@ public class ShadowPackageManagerTest {
@Test
public void getPackageInfo_uninstalledPackage_includeUninstalled() throws Exception {
packageManager.setApplicationEnabledSetting(
- RuntimeEnvironment.application.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, 0);
- PackageInfo info = packageManager.getPackageInfo(RuntimeEnvironment.application.getPackageName(), MATCH_UNINSTALLED_PACKAGES);
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ COMPONENT_ENABLED_STATE_DISABLED,
+ 0);
+ PackageInfo info =
+ packageManager.getPackageInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ MATCH_UNINSTALLED_PACKAGES);
assertThat(info).isNotNull();
- assertThat(info.packageName).isEqualTo(RuntimeEnvironment.application.getPackageName());
+ assertThat(info.packageName)
+ .isEqualTo(ApplicationProvider.getApplicationContext().getPackageName());
}
@Test
public void getPackageInfo_uninstalledPackage_dontIncludeUninstalled() {
packageManager.setApplicationEnabledSetting(
- RuntimeEnvironment.application.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, 0);
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ COMPONENT_ENABLED_STATE_DISABLED,
+ 0);
try {
- packageManager.getPackageInfo(RuntimeEnvironment.application.getPackageName(), 0);
+ packageManager.getPackageInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(), 0);
fail("should have thrown NameNotFoundException");
} catch (NameNotFoundException e) {
// expected
@@ -1358,26 +1465,36 @@ public class ShadowPackageManagerTest {
@Test
public void getPackageInfo_disabledPackage_includeDisabled() throws Exception {
packageManager.setApplicationEnabledSetting(
- RuntimeEnvironment.application.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, 0);
- PackageInfo info = packageManager.getPackageInfo(
- RuntimeEnvironment.application.getPackageName(), MATCH_DISABLED_COMPONENTS);
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ COMPONENT_ENABLED_STATE_DISABLED,
+ 0);
+ PackageInfo info =
+ packageManager.getPackageInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ MATCH_DISABLED_COMPONENTS);
assertThat(info).isNotNull();
- assertThat(info.packageName).isEqualTo(RuntimeEnvironment.application.getPackageName());
+ assertThat(info.packageName)
+ .isEqualTo(ApplicationProvider.getApplicationContext().getPackageName());
}
@Test
public void getInstalledPackages_uninstalledPackage_includeUninstalled() throws Exception {
packageManager.setApplicationEnabledSetting(
- RuntimeEnvironment.application.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, 0);
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ COMPONENT_ENABLED_STATE_DISABLED,
+ 0);
assertThat(packageManager.getInstalledPackages(MATCH_UNINSTALLED_PACKAGES)).isNotEmpty();
- assertThat(packageManager.getInstalledPackages(MATCH_UNINSTALLED_PACKAGES).get(0).packageName).isEqualTo(RuntimeEnvironment.application.getPackageName());
+ assertThat(packageManager.getInstalledPackages(MATCH_UNINSTALLED_PACKAGES).get(0).packageName)
+ .isEqualTo(ApplicationProvider.getApplicationContext().getPackageName());
}
@Test
public void getInstalledPackages_uninstalledPackage_dontIncludeUninstalled() throws Exception {
packageManager.setApplicationEnabledSetting(
- RuntimeEnvironment.application.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, 0);
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ COMPONENT_ENABLED_STATE_DISABLED,
+ 0);
assertThat(packageManager.getInstalledPackages(0)).isEmpty();
}
@@ -1385,11 +1502,13 @@ public class ShadowPackageManagerTest {
@Test
public void getInstalledPackages_disabledPackage_includeDisabled() throws Exception {
packageManager.setApplicationEnabledSetting(
- RuntimeEnvironment.application.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, 0);
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ COMPONENT_ENABLED_STATE_DISABLED,
+ 0);
assertThat(packageManager.getInstalledPackages(MATCH_DISABLED_COMPONENTS)).isNotEmpty();
assertThat(packageManager.getInstalledPackages(MATCH_DISABLED_COMPONENTS).get(0).packageName)
- .isEqualTo(RuntimeEnvironment.application.getPackageName());
+ .isEqualTo(ApplicationProvider.getApplicationContext().getPackageName());
}
@Test
@@ -1466,7 +1585,8 @@ public class ShadowPackageManagerTest {
@Test
public void shouldAssignTheAppMetaDataFromTheManifest() throws Exception {
ApplicationInfo info =
- packageManager.getApplicationInfo(RuntimeEnvironment.application.getPackageName(), 0);
+ packageManager.getApplicationInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(), 0);
Bundle meta = info.metaData;
assertThat(meta.getString("org.robolectric.metaName1")).isEqualTo("metaValue1");
@@ -1482,20 +1602,31 @@ public class ShadowPackageManagerTest {
assertThat(meta.getBoolean("org.robolectric.metaBooleanFromRes"))
.isEqualTo(
- RuntimeEnvironment.application.getResources().getBoolean(R.bool.false_bool_value));
+ ApplicationProvider.getApplicationContext()
+ .getResources()
+ .getBoolean(R.bool.false_bool_value));
assertThat(meta.getInt("org.robolectric.metaIntFromRes"))
.isEqualTo(
- RuntimeEnvironment.application.getResources().getInteger(R.integer.test_integer1));
+ ApplicationProvider.getApplicationContext()
+ .getResources()
+ .getInteger(R.integer.test_integer1));
assertThat(meta.getInt("org.robolectric.metaColorFromRes"))
- .isEqualTo(RuntimeEnvironment.application.getResources().getColor(R.color.clear));
+ .isEqualTo(
+ ApplicationProvider.getApplicationContext()
+ .getResources()
+ .getColor(R.color.clear));
assertThat(meta.getString("org.robolectric.metaStringFromRes"))
- .isEqualTo(RuntimeEnvironment.application.getString(R.string.app_name));
+ .isEqualTo(
+ ApplicationProvider.getApplicationContext()
+ .getString(R.string.app_name));
assertThat(meta.getString("org.robolectric.metaStringOfIntFromRes"))
- .isEqualTo(RuntimeEnvironment.application.getString(R.string.str_int));
+ .isEqualTo(
+ ApplicationProvider.getApplicationContext()
+ .getString(R.string.str_int));
assertThat(meta.getInt("org.robolectric.metaStringRes")).isEqualTo(R.string.app_name);
}
@@ -1572,7 +1703,9 @@ public class ShadowPackageManagerTest {
@Test
public void testSetComponentEnabledSetting() {
- ComponentName componentName = new ComponentName(RuntimeEnvironment.application, "org.robolectric.component");
+ ComponentName componentName =
+ new ComponentName(
+ ApplicationProvider.getApplicationContext(), "org.robolectric.component");
assertThat(packageManager.getComponentEnabledSetting(componentName)).isEqualTo(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
@@ -1583,6 +1716,28 @@ public class ShadowPackageManagerTest {
public static class ActivityWithMetadata extends Activity { }
@Test
+ public void getActivityInfo_disabledActivity() throws Exception {
+ ActivityInfo activityInfo =
+ packageManager.getActivityInfo(
+ new ComponentName("org.robolectric", "org.robolectric.shadows.DisabledActivity"),
+ PackageManager.MATCH_DISABLED_COMPONENTS);
+
+ assertThat(activityInfo).isNotNull();
+ assertThat(activityInfo.enabled).isFalse();
+ }
+
+ @Test
+ public void getServiceInfo_disabledService() throws Exception {
+ ServiceInfo activityInfo =
+ packageManager.getServiceInfo(
+ new ComponentName("org.robolectric", "org.robolectric.shadows.DisabledService"),
+ PackageManager.MATCH_DISABLED_COMPONENTS);
+
+ assertThat(activityInfo).isNotNull();
+ assertThat(activityInfo.enabled).isFalse();
+ }
+
+ @Test
public void getActivityMetaData() throws Exception {
Activity activity = setupActivity(ActivityWithMetadata.class);
@@ -1599,23 +1754,27 @@ public class ShadowPackageManagerTest {
@Test
public void getServiceInfo_shouldReturnServiceInfoIfExists() throws Exception {
- ServiceInfo serviceInfo = packageManager.getServiceInfo(new ComponentName("org.robolectric", "com.foo.Service"), PackageManager.GET_SERVICES);
- assertEquals("org.robolectric", serviceInfo.packageName);
- assertEquals("com.foo.Service", serviceInfo.name);
- assertEquals("com.foo.MY_PERMISSION", serviceInfo.permission);
- assertNotNull(serviceInfo.applicationInfo);
+ ComponentName component = new ComponentName("org.robolectric", "com.foo.Service");
+ ServiceInfo serviceInfo = packageManager.getServiceInfo(component, 0);
+ assertThat(serviceInfo.packageName).isEqualTo("org.robolectric");
+ assertThat(serviceInfo.processName).isEqualTo("org.robolectric");
+ assertThat(serviceInfo.name).isEqualTo("com.foo.Service");
+ assertThat(serviceInfo.permission).isEqualTo("com.foo.MY_PERMISSION");
+ assertThat(serviceInfo.applicationInfo).isNotNull();
}
@Test
public void getServiceInfo_shouldReturnServiceInfoWithMetaDataWhenFlagsSet() throws Exception {
- ServiceInfo serviceInfo = packageManager.getServiceInfo(new ComponentName("org.robolectric", "com.foo.Service"), PackageManager.GET_META_DATA);
- assertNotNull(serviceInfo.metaData);
+ ComponentName component = new ComponentName("org.robolectric", "com.foo.Service");
+ ServiceInfo serviceInfo = packageManager.getServiceInfo(component, PackageManager.GET_META_DATA);
+ assertThat(serviceInfo.metaData).isNotNull();
}
@Test
public void getServiceInfo_shouldReturnServiceInfoWithoutMetaDataWhenFlagsNotSet() throws Exception {
- ServiceInfo serviceInfo = packageManager.getServiceInfo(new ComponentName("org.robolectric", "com.foo.Service"), PackageManager.GET_SERVICES);
- assertNull(serviceInfo.metaData);
+ ComponentName component = new ComponentName("org.robolectric", "com.foo.Service");
+ ServiceInfo serviceInfo = packageManager.getServiceInfo(component, 0);
+ assertThat(serviceInfo.metaData).isNull();
}
@Test
@@ -1667,8 +1826,13 @@ public class ShadowPackageManagerTest {
@Test
public void getResourcesForApplication_currentApplication() throws Exception {
- assertThat(packageManager.getResourcesForApplication("org.robolectric").getString(R.string.app_name))
- .isEqualTo(RuntimeEnvironment.application.getString(R.string.app_name));
+ assertThat(
+ packageManager
+ .getResourcesForApplication("org.robolectric")
+ .getString(R.string.app_name))
+ .isEqualTo(
+ ApplicationProvider.getApplicationContext()
+ .getString(R.string.app_name));
}
@Test
@@ -1692,7 +1856,8 @@ public class ShadowPackageManagerTest {
shadowPackageManager.addPackage(packageInfo);
assertThat(packageManager.getResourcesForApplication("another.package")).isNotNull();
- assertThat(packageManager.getResourcesForApplication("another.package")).isNotEqualTo(RuntimeEnvironment.application.getResources());
+ assertThat(packageManager.getResourcesForApplication("another.package"))
+ .isNotEqualTo(ApplicationProvider.getApplicationContext().getResources());
}
@Test @Config(minSdk = M)
@@ -1846,7 +2011,7 @@ public class ShadowPackageManagerTest {
@Test
public void getPermissionInfo() throws Exception {
PermissionInfo permission =
- RuntimeEnvironment.application
+ ApplicationProvider.getApplicationContext()
.getPackageManager()
.getPermissionInfo("org.robolectric.some_permission", 0);
assertThat(permission.labelRes).isEqualTo(R.string.test_permission_label);
@@ -2053,9 +2218,11 @@ public class ShadowPackageManagerTest {
@Test
public void getXml() throws Exception {
- XmlResourceParser in = packageManager.getXml(RuntimeEnvironment.application.getPackageName(),
- R.xml.dialog_preferences,
- RuntimeEnvironment.application.getApplicationInfo());
+ XmlResourceParser in =
+ packageManager.getXml(
+ ApplicationProvider.getApplicationContext().getPackageName(),
+ R.xml.dialog_preferences,
+ ApplicationProvider.getApplicationContext().getApplicationInfo());
assertThat(in).isNotNull();
}
@@ -2091,9 +2258,12 @@ public class ShadowPackageManagerTest {
@Test
public void deletePackage() throws Exception {
// Apps must have the android.permission.DELETE_PACKAGES set to delete packages.
- PackageManager packageManager = RuntimeEnvironment.application.getPackageManager();
- packageManager.getPackageInfo(RuntimeEnvironment.application.getPackageName(), 0).requestedPermissions =
- new String[] { android.Manifest.permission.DELETE_PACKAGES };
+ PackageManager packageManager =
+ ApplicationProvider.getApplicationContext().getPackageManager();
+ packageManager.getPackageInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(), 0)
+ .requestedPermissions =
+ new String[] {android.Manifest.permission.DELETE_PACKAGES};
PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "test.package";
@@ -2129,7 +2299,9 @@ public class ShadowPackageManagerTest {
public void getIntentFiltersForActivity() throws NameNotFoundException {
List<IntentFilter> intentFilters =
shadowPackageManager.getIntentFiltersForActivity(
- new ComponentName(RuntimeEnvironment.application, ActivityWithFilters.class));
+ new ComponentName(
+ ApplicationProvider.getApplicationContext(),
+ ActivityWithFilters.class));
assertThat(intentFilters).hasSize(1);
IntentFilter intentFilter = intentFilters.get(0);
assertThat(intentFilter.getCategory(0)).isEqualTo(Intent.CATEGORY_DEFAULT);
@@ -2140,7 +2312,8 @@ public class ShadowPackageManagerTest {
@Test
public void getPackageInfo_shouldHaveWritableDataDirs() throws Exception {
PackageInfo packageInfo =
- packageManager.getPackageInfo(RuntimeEnvironment.application.getPackageName(), 0);
+ packageManager.getPackageInfo(
+ ApplicationProvider.getApplicationContext().getPackageName(), 0);
File dataDir = new File(packageInfo.applicationInfo.dataDir);
assertThat(dataDir.isDirectory()).isTrue();
@@ -2160,7 +2333,8 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void getApplicationHiddenSettingAsUser_hidden() throws Exception {
- String packageName = RuntimeEnvironment.application.getPackageName();
+ String packageName =
+ ApplicationProvider.getApplicationContext().getPackageName();
packageManager.setApplicationHiddenSettingAsUser(
packageName, /* hidden= */ true, /* user= */ null);
@@ -2172,7 +2346,8 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void getApplicationHiddenSettingAsUser_notHidden() throws Exception {
- String packageName = RuntimeEnvironment.application.getPackageName();
+ String packageName =
+ ApplicationProvider.getApplicationContext().getPackageName();
assertThat(packageManager.getApplicationHiddenSettingAsUser(packageName, /* user= */ null))
.isFalse();
@@ -2188,7 +2363,8 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void setApplicationHiddenSettingAsUser_includeUninstalled() throws Exception {
- String packageName = RuntimeEnvironment.application.getPackageName();
+ String packageName =
+ ApplicationProvider.getApplicationContext().getPackageName();
packageManager.setApplicationHiddenSettingAsUser(
packageName, /* hidden= */ true, /* user= */ null);
@@ -2205,7 +2381,8 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP)
public void setApplicationHiddenSettingAsUser_dontIncludeUninstalled() throws Exception {
- String packageName = RuntimeEnvironment.application.getPackageName();
+ String packageName =
+ ApplicationProvider.getApplicationContext().getPackageName();
packageManager.setApplicationHiddenSettingAsUser(
packageName, /* hidden= */ true, /* user= */ null);
@@ -2230,7 +2407,8 @@ public class ShadowPackageManagerTest {
@Test
@Config(minSdk = LOLLIPOP_MR1)
public void setUnbadgedApplicationIcon() throws Exception {
- String packageName = RuntimeEnvironment.application.getPackageName();
+ String packageName =
+ ApplicationProvider.getApplicationContext().getPackageName();
Drawable d = new BitmapDrawable();
shadowPackageManager.setUnbadgedApplicationIcon(packageName, d);
@@ -2256,9 +2434,10 @@ public class ShadowPackageManagerTest {
}
@Test
- @Config(minSdk = android.os.Build.VERSION_CODES.P, packageName = "com.self.package")
+ @Config(minSdk = android.os.Build.VERSION_CODES.P)
public void isPackageSuspended_callersPackage_shouldReturnFalse() throws NameNotFoundException {
- assertThat(packageManager.isPackageSuspended("com.self.package")).isFalse();
+ assertThat(packageManager.isPackageSuspended(ApplicationProvider.getApplicationContext().getPackageName()))
+ .isFalse();
}
@Test
@@ -2308,7 +2487,8 @@ public class ShadowPackageManagerTest {
public void setPackagesSuspended_withProfileOwner_shouldThrow() {
DevicePolicyManager devicePolicyManager =
(DevicePolicyManager)
- RuntimeEnvironment.application.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ ApplicationProvider.getApplicationContext()
+ .getSystemService(Context.DEVICE_POLICY_SERVICE);
shadowOf(devicePolicyManager)
.setProfileOwner(new ComponentName("com.profile.owner", "ProfileOwnerClass"));
try {
@@ -2328,7 +2508,8 @@ public class ShadowPackageManagerTest {
public void setPackagesSuspended_withDeviceOwner_shouldThrow() {
DevicePolicyManager devicePolicyManager =
(DevicePolicyManager)
- RuntimeEnvironment.application.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ ApplicationProvider.getApplicationContext()
+ .getSystemService(Context.DEVICE_POLICY_SERVICE);
shadowOf(devicePolicyManager)
.setDeviceOwner(new ComponentName("com.device.owner", "DeviceOwnerClass"));
// Robolectric uses a random UID (see ShadowProcess#getRandomApplicationUid) that falls within
@@ -2347,7 +2528,7 @@ public class ShadowPackageManagerTest {
}
@Test
- @Config(minSdk = android.os.Build.VERSION_CODES.P, packageName = "com.self.package")
+ @Config(minSdk = android.os.Build.VERSION_CODES.P)
public void setPackagesSuspended_shouldSuspendSuspendablePackagesAndReturnTheRest()
throws NameNotFoundException {
shadowPackageManager.addPackage(createPackageInfoWithPackageName("android"));
@@ -2361,19 +2542,24 @@ public class ShadowPackageManagerTest {
"com.suspendable.package1",
"android", // Unsuspendable (platform package).
"com.suspendable.package2",
- "com.self.package" // Unsuspendable (caller's package).
+ ApplicationProvider.getApplicationContext()
+ .getPackageName() // Unsuspendable (caller's package).
},
/* suspended= */ true,
/* appExtras= */ null,
/* launcherExtras= */ null,
/* dialogMessage= */ (String) null))
.asList()
- .containsExactly("com.nonexistent.package", "android", "com.self.package");
+ .containsExactly(
+ "com.nonexistent.package", "android",
+ ApplicationProvider.getApplicationContext().getPackageName());
assertThat(packageManager.isPackageSuspended("com.suspendable.package1")).isTrue();
assertThat(packageManager.isPackageSuspended("android")).isFalse();
assertThat(packageManager.isPackageSuspended("com.suspendable.package2")).isTrue();
- assertThat(packageManager.isPackageSuspended("com.self.package")).isFalse();
+ assertThat(packageManager.isPackageSuspended(
+ ApplicationProvider.getApplicationContext().getPackageName()))
+ .isFalse();
}
@Test
@@ -2404,7 +2590,7 @@ public class ShadowPackageManagerTest {
}
@Test
- @Config(minSdk = android.os.Build.VERSION_CODES.P, packageName = "com.self.package")
+ @Config(minSdk = android.os.Build.VERSION_CODES.P)
public void setPackagesSuspended_shouldUnsuspendSuspendablePackagesAndReturnTheRest()
throws NameNotFoundException {
shadowPackageManager.addPackage(createPackageInfoWithPackageName("android"));
@@ -2426,19 +2612,22 @@ public class ShadowPackageManagerTest {
"com.suspendable.package1",
"android", // Unsuspendable (platform package).
"com.suspendable.package2",
- "com.self.package" // Unsuspendable (caller's package).
+ ApplicationProvider.getApplicationContext()
+ .getPackageName() // Unsuspendable (caller's package).
},
/* suspended= */ false,
/* appExtras= */ null,
/* launcherExtras= */ null,
/* dialogMessage= */ (String) null))
.asList()
- .containsExactly("com.nonexistent.package", "android", "com.self.package");
+ .containsExactly(
+ "com.nonexistent.package", "android", ApplicationProvider.getApplicationContext().getPackageName());
assertThat(packageManager.isPackageSuspended("com.suspendable.package1")).isFalse();
assertThat(packageManager.isPackageSuspended("android")).isFalse();
assertThat(packageManager.isPackageSuspended("com.suspendable.package2")).isFalse();
- assertThat(packageManager.isPackageSuspended("com.self.package")).isFalse();
+ assertThat(packageManager.isPackageSuspended(ApplicationProvider.getApplicationContext().getPackageName()))
+ .isFalse();
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPaintTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPaintTest.java
index 64a6f8941..7921b6fa8 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPaintTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPaintTest.java
@@ -7,12 +7,12 @@ import static org.robolectric.Shadows.shadowOf;
import android.graphics.Color;
import android.graphics.Paint;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowPaintTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPairTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPairTest.java
index 346063908..20929e114 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPairTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPairTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.util.Pair;
+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 ShadowPairTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowParcelFileDescriptorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowParcelFileDescriptorTest.java
index 0831dfc1f..3d023f750 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowParcelFileDescriptorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowParcelFileDescriptorTest.java
@@ -1,55 +1,63 @@
package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assume.assumeTrue;
-import static org.robolectric.shadows.ShadowAssetManager.useLegacy;
import android.os.ParcelFileDescriptor;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
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 ShadowParcelFileDescriptorTest {
+
+ private static final int READ_ONLY_FILE_CONTENTS = 42;
+
private File file;
private File readOnlyFile;
@Before
- public void setup() throws Exception {
- assumeTrue(useLegacy());
- file = new File(RuntimeEnvironment.application.getFilesDir(), "test");
+ public void setUp() throws Exception {
+ file = new File(ApplicationProvider.getApplicationContext().getFilesDir(), "test");
FileOutputStream os = new FileOutputStream(file);
os.close();
- readOnlyFile = new File(RuntimeEnvironment.application.getFilesDir(), "test_readonly");
+ readOnlyFile =
+ new File(ApplicationProvider.getApplicationContext().getFilesDir(), "test_readonly");
os = new FileOutputStream(readOnlyFile);
+ os.write(READ_ONLY_FILE_CONTENTS);
os.close();
- readOnlyFile.setReadOnly();
+ assertThat(readOnlyFile.setReadOnly()).isTrue();
}
@Test
public void testOpens() throws Exception {
- ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
+ ParcelFileDescriptor pfd =
+ ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
assertThat(pfd).isNotNull();
assertThat(pfd.getFileDescriptor().valid()).isTrue();
pfd.close();
}
@Test
- public void testOpens_readOnlyFile() throws Exception {
- ParcelFileDescriptor pfd = ParcelFileDescriptor.open(readOnlyFile, ParcelFileDescriptor.MODE_READ_ONLY);
+ public void testOpens_canReadReadOnlyFile() throws Exception {
+ ParcelFileDescriptor pfd =
+ ParcelFileDescriptor.open(readOnlyFile, ParcelFileDescriptor.MODE_READ_ONLY);
assertThat(pfd).isNotNull();
assertThat(pfd.getFileDescriptor().valid()).isTrue();
+ FileInputStream is = new FileInputStream(pfd.getFileDescriptor());
+ assertThat(is.read()).isEqualTo(READ_ONLY_FILE_CONTENTS);
pfd.close();
}
@Test
public void testOpens_canWriteWritableFile() throws Exception {
- ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
+ ParcelFileDescriptor pfd =
+ ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
assertThat(pfd).isNotNull();
assertThat(pfd.getFileDescriptor().valid()).isTrue();
FileOutputStream os = new FileOutputStream(pfd.getFileDescriptor());
@@ -59,7 +67,8 @@ public class ShadowParcelFileDescriptorTest {
@Test
public void testStatSize_emptyFile() throws Exception {
- ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
+ ParcelFileDescriptor pfd =
+ ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
assertThat(pfd).isNotNull();
assertThat(pfd.getFileDescriptor().valid()).isTrue();
assertThat(pfd.getStatSize()).isEqualTo(0);
@@ -68,12 +77,13 @@ public class ShadowParcelFileDescriptorTest {
@Test
public void testStatSize_writtenFile() throws Exception {
- ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
+ ParcelFileDescriptor pfd =
+ ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
assertThat(pfd).isNotNull();
assertThat(pfd.getFileDescriptor().valid()).isTrue();
FileOutputStream os = new FileOutputStream(pfd.getFileDescriptor());
os.write(5);
- assertThat(pfd.getStatSize()).isEqualTo(1); // One byte.
+ assertThat(pfd.getStatSize()).isEqualTo(1); // One byte.
os.close();
}
@@ -82,21 +92,24 @@ public class ShadowParcelFileDescriptorTest {
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, -1);
pfd.close();
assertThat(pfd.getFileDescriptor().valid()).isFalse();
+ assertThat(pfd.getFd()).isEqualTo(-1);
}
@Test
public void testAutoCloseInputStream() throws Exception {
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, -1);
- ParcelFileDescriptor.AutoCloseInputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
+ ParcelFileDescriptor.AutoCloseInputStream is =
+ new ParcelFileDescriptor.AutoCloseInputStream(pfd);
is.close();
assertThat(pfd.getFileDescriptor().valid()).isFalse();
}
@Test
public void testAutoCloseOutputStream() throws Exception {
- File f = new File(RuntimeEnvironment.application.getFilesDir(), "outfile");
+ File f = new File(ApplicationProvider.getApplicationContext().getFilesDir(), "outfile");
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(f, -1);
- ParcelFileDescriptor.AutoCloseOutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(pfd);
+ ParcelFileDescriptor.AutoCloseOutputStream os =
+ new ParcelFileDescriptor.AutoCloseOutputStream(pfd);
os.close();
assertThat(pfd.getFileDescriptor().valid()).isFalse();
}
@@ -106,9 +119,11 @@ public class ShadowParcelFileDescriptorTest {
ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
ParcelFileDescriptor readSide = pipe[0];
ParcelFileDescriptor writeSide = pipe[1];
- byte[] dataToWrite = new byte[] {0,1,2,3,4};
- ParcelFileDescriptor.AutoCloseInputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(readSide);
- ParcelFileDescriptor.AutoCloseOutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream(writeSide);
+ byte[] dataToWrite = new byte[] {0, 1, 2, 3, 4};
+ ParcelFileDescriptor.AutoCloseInputStream inputStream =
+ new ParcelFileDescriptor.AutoCloseInputStream(readSide);
+ ParcelFileDescriptor.AutoCloseOutputStream outputStream =
+ new ParcelFileDescriptor.AutoCloseOutputStream(writeSide);
outputStream.write(dataToWrite);
byte[] read = new byte[dataToWrite.length];
int byteCount = inputStream.read(read);
@@ -117,4 +132,15 @@ public class ShadowParcelFileDescriptorTest {
assertThat(byteCount).isEqualTo(dataToWrite.length);
assertThat(read).isEqualTo(dataToWrite);
}
+
+ @Test
+ public void testGetFd_canRead() throws IOException {
+ ParcelFileDescriptor pfd =
+ ParcelFileDescriptor.open(readOnlyFile, ParcelFileDescriptor.MODE_READ_ONLY);
+ int fd = pfd.getFd();
+ assertThat(fd).isGreaterThan(0);
+ FileInputStream is = new FileInputStream(new File("/proc/self/fd/" + fd));
+ assertThat(is.read()).isEqualTo(READ_ONLY_FILE_CONTENTS);
+ is.close();
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowParcelTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowParcelTest.java
index 2e22f5d16..b6e15eb77 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowParcelTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowParcelTest.java
@@ -11,6 +11,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -20,10 +21,9 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowParcelTest {
private Parcel parcel;
@@ -639,7 +639,7 @@ public class ShadowParcelTest {
parcel.setDataCapacity(8);
assertThat(parcel.dataCapacity()).isEqualTo(8);
}
-
+
@Test
public void testWriteAndEnforceCompatibleInterface() {
parcel.writeInterfaceToken("com.example.IMyInterface");
@@ -647,7 +647,7 @@ public class ShadowParcelTest {
parcel.enforceInterface("com.example.IMyInterface");
// Nothing explodes
}
-
+
@Test
public void testWriteAndEnforceIncompatibleInterface() {
parcel.writeInterfaceToken("com.example.Derp");
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPasswordTransformationMethodTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPasswordTransformationMethodTest.java
index cf8c7e877..452b7ccd3 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPasswordTransformationMethodTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPasswordTransformationMethodTest.java
@@ -3,12 +3,12 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.text.method.PasswordTransformationMethod;
+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 ShadowPasswordTransformationMethodTest {
private PasswordTransformationMethod transformationMethod;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPathTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPathTest.java
index 3664ec2f9..617650b42 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPathTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPathTest.java
@@ -1,32 +1,22 @@
package org.robolectric.shadows;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
import static org.robolectric.Shadows.shadowOf;
import static org.robolectric.shadows.ShadowPath.Point.Type.LINE_TO;
import static org.robolectric.shadows.ShadowPath.Point.Type.MOVE_TO;
import android.graphics.Path;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowPathTest {
@Test
- public void testGradTo() {
- Path path = Shadow.newInstanceOf(Path.class);
- path.quadTo(0, 5, 10, 15);
- ShadowPath shadowPath = shadowOf(path);
- assertEquals(shadowPath.getQuadDescription(), "Add a quadratic bezier from last point, approaching (0.0,5.0), ending at (10.0,15.0)");
- }
-
- @Test
public void testMoveTo() throws Exception {
- Path path = Shadow.newInstanceOf(Path.class);
+ Path path = new Path();
path.moveTo(2, 3);
path.moveTo(3, 4);
@@ -38,7 +28,7 @@ public class ShadowPathTest {
@Test
public void testLineTo() throws Exception {
- Path path = Shadow.newInstanceOf(Path.class);
+ Path path = new Path();
path.lineTo(2, 3);
path.lineTo(3, 4);
@@ -50,7 +40,7 @@ public class ShadowPathTest {
@Test
public void testReset() throws Exception {
- Path path = Shadow.newInstanceOf(Path.class);
+ Path path = new Path();
path.moveTo(0, 3);
path.lineTo(2, 3);
path.quadTo(2, 3, 4, 5);
@@ -59,20 +49,16 @@ public class ShadowPathTest {
ShadowPath shadowPath = shadowOf(path);
List<ShadowPath.Point> points = shadowPath.getPoints();
assertEquals(0, points.size());
- assertNull(shadowPath.getWasMovedTo());
- assertEquals("", shadowPath.getQuadDescription());
}
@Test
public void test_copyConstructor() throws Exception {
- Path path = Shadow.newInstanceOf(Path.class);
+ Path path = new Path();
path.moveTo(0, 3);
path.lineTo(2, 3);
path.quadTo(2, 3, 4, 5);
Path copiedPath = new Path(path);
assertEquals(shadowOf(path).getPoints(), shadowOf(copiedPath).getPoints());
- assertEquals(shadowOf(path).getWasMovedTo(), shadowOf(copiedPath).getWasMovedTo());
- assertEquals(shadowOf(path).getQuadDescription(), shadowOf(copiedPath).getQuadDescription());
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPeerHandleTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPeerHandleTest.java
index 7e7f8ba38..c172cd415 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPeerHandleTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPeerHandleTest.java
@@ -4,13 +4,13 @@ import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
import android.net.wifi.aware.PeerHandle;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** Tests for {@link ShadowPeerHandle}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = O)
public class ShadowPeerHandleTest {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPendingIntentTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPendingIntentTest.java
index b11179739..a65f30162 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPendingIntentTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPendingIntentTest.java
@@ -10,28 +10,29 @@ import static org.junit.Assert.fail;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
+import android.app.Application;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
+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.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowPendingIntentTest {
private Context context;
@Before
public void setUp() {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
}
@Test
@@ -75,7 +76,8 @@ public class ShadowPendingIntentTest {
assertThat(shadow.getSavedIntents()).isEqualTo(intents);
pendingIntent.send();
- ShadowApplication application = shadowOf(RuntimeEnvironment.application);
+ ShadowApplication application =
+ shadowOf((Application) ApplicationProvider.getApplicationContext());
assertThat(application.getNextStartedActivity()).isEqualTo(intents[1]);
assertThat(application.getNextStartedActivity()).isEqualTo(intents[0]);
}
@@ -90,7 +92,8 @@ public class ShadowPendingIntentTest {
assertThat(shadow.getSavedIntents()).isEqualTo(intents);
pendingIntent.send();
- ShadowApplication application = shadowOf(RuntimeEnvironment.application);
+ ShadowApplication application =
+ shadowOf((Application) ApplicationProvider.getApplicationContext());
assertThat(application.getNextStartedActivity()).isEqualTo(intents[1]);
assertThat(application.getNextStartedActivity()).isEqualTo(intents[0]);
}
@@ -320,7 +323,8 @@ public class ShadowPendingIntentTest {
@Test
public void getActivities_withFlagNoCreate_shouldReturnExistingIntent() {
Intent[] intents = {new Intent(Intent.ACTION_VIEW), new Intent(Intent.ACTION_PICK)};
- PendingIntent.getActivities(RuntimeEnvironment.application, 99, intents, 100);
+ PendingIntent.getActivities(
+ (Application) ApplicationProvider.getApplicationContext(), 99, intents, 100);
Intent[] identicalIntents = {new Intent(Intent.ACTION_VIEW), new Intent(Intent.ACTION_PICK)};
PendingIntent saved =
@@ -332,7 +336,8 @@ public class ShadowPendingIntentTest {
@Test
public void getActivities_withNoFlags_shouldReturnExistingIntent() {
Intent[] intents = {new Intent(Intent.ACTION_VIEW), new Intent(Intent.ACTION_PICK)};
- PendingIntent.getActivities(RuntimeEnvironment.application, 99, intents, 100);
+ PendingIntent.getActivities(
+ (Application) ApplicationProvider.getApplicationContext(), 99, intents, 100);
Intent[] identicalIntents = {new Intent(Intent.ACTION_VIEW), new Intent(Intent.ACTION_PICK)};
PendingIntent saved = PendingIntent.getActivities(context, 99, identicalIntents, 0);
@@ -625,7 +630,7 @@ public class ShadowPendingIntentTest {
@Test
public void testHashCode() {
- Context ctx = RuntimeEnvironment.application;
+ Context ctx = (Application) ApplicationProvider.getApplicationContext();
PendingIntent pendingIntent1 = PendingIntent.getActivity(ctx, 99, new Intent("activity"), 100);
assertThat(pendingIntent1.hashCode())
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPhoneWindowTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPhoneWindowTest.java
index 2fb624b15..b534341fa 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPhoneWindowTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPhoneWindowTest.java
@@ -6,13 +6,13 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.view.Window;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowPhoneWindowTest {
private Window window;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPictureTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPictureTest.java
index 74f0c3990..6aaaa2604 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPictureTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPictureTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.graphics.Picture;
+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 ShadowPictureTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPopupMenuTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPopupMenuTest.java
index 4642eafef..46e8cafbf 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPopupMenuTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPopupMenuTest.java
@@ -3,16 +3,17 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.view.MenuItem;
import android.view.View;
import android.widget.PopupMenu;
+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 ShadowPopupMenuTest {
private PopupMenu popupMenu;
@@ -20,8 +21,9 @@ public class ShadowPopupMenuTest {
@Before
public void setUp() {
- View anchorView = new View(RuntimeEnvironment.application);
- popupMenu = new PopupMenu(RuntimeEnvironment.application, anchorView);
+ View anchorView = new View((Application) ApplicationProvider.getApplicationContext());
+ popupMenu =
+ new PopupMenu((Application) ApplicationProvider.getApplicationContext(), anchorView);
shadowPopupMenu = shadowOf(popupMenu);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPorterDuffColorFilterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPorterDuffColorFilterTest.java
index b2789d5ef..d144019e3 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPorterDuffColorFilterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPorterDuffColorFilterTest.java
@@ -1,17 +1,18 @@
package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
+import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowPorterDuffColorFilterTest {
@Test
@@ -21,6 +22,13 @@ public class ShadowPorterDuffColorFilterTest {
assertThat(filter.getMode()).isEqualTo(PorterDuff.Mode.ADD);
}
+ @Config(minSdk = O)
+ @Test
+ public void createNativeInstance_shouldWork() {
+ final PorterDuffColorFilter filter = new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.ADD);
+ assertThat(filter.getNativeInstance()).isEqualTo(0L);
+ }
+
@Test
public void hashCode_returnsDifferentValuesForDifferentModes() {
PorterDuffColorFilter addFilter = new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.ADD);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPowerManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPowerManagerTest.java
index 4b72b2c4d..b2d217ccc 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPowerManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPowerManagerTest.java
@@ -5,24 +5,28 @@ import static android.os.Build.VERSION_CODES.M;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.os.PowerManager;
import android.os.WorkSource;
+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;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowPowerManagerTest {
private PowerManager powerManager;
private ShadowPowerManager shadowPowerManager;
@Before
public void before() {
- powerManager = (PowerManager) RuntimeEnvironment.application.getSystemService(Context.POWER_SERVICE);
+ powerManager =
+ (PowerManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.POWER_SERVICE);
shadowPowerManager = shadowOf(powerManager);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceActivityTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceActivityTest.java
index 105f3c828..9eefefc7b 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceActivityTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceActivityTest.java
@@ -4,14 +4,14 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNotNull;
import android.preference.PreferenceActivity;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowPreferenceActivityTest {
private TestPreferenceActivity activity;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceActivityTestWithFragment.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceActivityTestWithFragment.java
index d7554fb90..3b139a6cd 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceActivityTestWithFragment.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceActivityTestWithFragment.java
@@ -7,20 +7,19 @@ import android.app.FragmentManager;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
/**
- * Current Android examples show adding a PreferenceFragment as part of the
- * hosting Activity lifecycle. This resulted in a null pointer exception when
- * trying to access a Context while inflating the Preference objects defined in
- * xml. This class tests that path.
+ * Current Android examples show adding a PreferenceFragment as part of the hosting Activity
+ * lifecycle. This resulted in a null pointer exception when trying to access a Context while
+ * inflating the Preference objects defined in xml. This class tests that path.
*/
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowPreferenceActivityTestWithFragment {
private TestPreferenceActivity activity = Robolectric.setupActivity(TestPreferenceActivity.class);
private TestPreferenceFragment fragment;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceGroupTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceGroupTest.java
index e95ed13af..5decabda6 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceGroupTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPreferenceGroupTest.java
@@ -10,13 +10,13 @@ import android.preference.Preference;
import android.preference.PreferenceGroup;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowPreferenceGroupTest {
private TestPreferenceGroup group;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowProcessTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowProcessTest.java
index e0d2cfed4..a443314ed 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowProcessTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowProcessTest.java
@@ -2,14 +2,14 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
/** Test ShadowProcess */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowProcessTest {
@Test
public void shouldBeZeroWhenNotSet() {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowProgressBarTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowProgressBarTest.java
index 0c0fb0681..5f15836ef 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowProgressBarTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowProgressBarTest.java
@@ -8,13 +8,13 @@ import static org.robolectric.RuntimeEnvironment.application;
import android.util.AttributeSet;
import android.widget.ProgressBar;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowProgressBarTest {
private int[] testValues = {0, 1, 2, 100};
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowProgressDialogTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowProgressDialogTest.java
index a820388b0..0dabde28f 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowProgressDialogTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowProgressDialogTest.java
@@ -3,16 +3,17 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.ProgressDialog;
import android.view.View;
+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;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowProgressDialogTest {
private ProgressDialog dialog;
@@ -20,7 +21,7 @@ public class ShadowProgressDialogTest {
@Before
public void setUp() {
- dialog = new ProgressDialog(RuntimeEnvironment.application);
+ dialog = new ProgressDialog((Application) ApplicationProvider.getApplicationContext());
shadow = Shadows.shadowOf(dialog);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowRadioButtonTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowRadioButtonTest.java
index 09483abe2..59a9fc690 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowRadioButtonTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowRadioButtonTest.java
@@ -5,20 +5,22 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.graphics.drawable.ColorDrawable;
import android.widget.RadioButton;
import android.widget.RadioGroup;
+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.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowRadioButtonTest {
@Test
public void canBeExplicitlyChecked() throws Exception {
- RadioButton radioButton = new RadioButton(RuntimeEnvironment.application);
+ RadioButton radioButton =
+ new RadioButton((Application) ApplicationProvider.getApplicationContext());
assertFalse(radioButton.isChecked());
radioButton.setChecked(true);
@@ -30,7 +32,8 @@ public class ShadowRadioButtonTest {
@Test
public void canBeToggledBetweenCheckedState() throws Exception {
- RadioButton radioButton = new RadioButton(RuntimeEnvironment.application);
+ RadioButton radioButton =
+ new RadioButton((Application) ApplicationProvider.getApplicationContext());
assertFalse(radioButton.isChecked());
radioButton.toggle();
@@ -42,7 +45,8 @@ public class ShadowRadioButtonTest {
@Test
public void canBeClickedToToggleCheckedState() throws Exception {
- RadioButton radioButton = new RadioButton(RuntimeEnvironment.application);
+ RadioButton radioButton =
+ new RadioButton((Application) ApplicationProvider.getApplicationContext());
assertFalse(radioButton.isChecked());
radioButton.performClick();
@@ -54,12 +58,15 @@ public class ShadowRadioButtonTest {
@Test
public void shouldInformRadioGroupThatItIsChecked() throws Exception {
- RadioButton radioButton1 = new RadioButton(RuntimeEnvironment.application);
+ RadioButton radioButton1 =
+ new RadioButton((Application) ApplicationProvider.getApplicationContext());
radioButton1.setId(99);
- RadioButton radioButton2 = new RadioButton(RuntimeEnvironment.application);
+ RadioButton radioButton2 =
+ new RadioButton((Application) ApplicationProvider.getApplicationContext());
radioButton2.setId(100);
- RadioGroup radioGroup = new RadioGroup(RuntimeEnvironment.application);
+ RadioGroup radioGroup =
+ new RadioGroup((Application) ApplicationProvider.getApplicationContext());
radioGroup.addView(radioButton1);
radioGroup.addView(radioButton2);
@@ -72,7 +79,8 @@ public class ShadowRadioButtonTest {
@Test
public void getButtonDrawableId() {
- RadioButton radioButton = new RadioButton(RuntimeEnvironment.application);
+ RadioButton radioButton =
+ new RadioButton((Application) ApplicationProvider.getApplicationContext());
radioButton.setButtonDrawable(R.drawable.an_image);
assertThat(shadowOf(radioButton).getButtonDrawableId()).isEqualTo(R.drawable.an_image);
@@ -80,7 +88,8 @@ public class ShadowRadioButtonTest {
@Test
public void getButtonDrawable() {
- RadioButton radioButton = new RadioButton(RuntimeEnvironment.application);
+ RadioButton radioButton =
+ new RadioButton((Application) ApplicationProvider.getApplicationContext());
ColorDrawable drawable = new ColorDrawable();
radioButton.setButtonDrawable(drawable);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowRadioGroupTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowRadioGroupTest.java
index bb9ae2b26..f8eee250a 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowRadioGroupTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowRadioGroupTest.java
@@ -3,21 +3,23 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import android.app.Application;
import android.widget.RadioGroup;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.Arrays;
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 ShadowRadioGroupTest {
private static final int BUTTON_ID = 3245;
@Test
public void checkedRadioButtonId() throws Exception {
- RadioGroup radioGroup = new RadioGroup(RuntimeEnvironment.application);
+ RadioGroup radioGroup =
+ new RadioGroup((Application) ApplicationProvider.getApplicationContext());
assertThat(radioGroup.getCheckedRadioButtonId()).isEqualTo(-1);
radioGroup.check(99);
assertThat(radioGroup.getCheckedRadioButtonId()).isEqualTo(99);
@@ -25,7 +27,8 @@ public class ShadowRadioGroupTest {
@Test
public void check_shouldCallOnCheckedChangeListener() throws Exception {
- RadioGroup radioGroup = new RadioGroup(RuntimeEnvironment.application);
+ RadioGroup radioGroup =
+ new RadioGroup((Application) ApplicationProvider.getApplicationContext());
TestOnCheckedChangeListener listener = new TestOnCheckedChangeListener();
radioGroup.setOnCheckedChangeListener(listener);
@@ -37,7 +40,8 @@ public class ShadowRadioGroupTest {
@Test
public void clearCheck_shouldCallOnCheckedChangeListenerTwice() throws Exception {
- RadioGroup radioGroup = new RadioGroup(RuntimeEnvironment.application);
+ RadioGroup radioGroup =
+ new RadioGroup((Application) ApplicationProvider.getApplicationContext());
TestOnCheckedChangeListener listener = new TestOnCheckedChangeListener();
radioGroup.check(BUTTON_ID);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowRatingBarTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowRatingBarTest.java
index 102c5023b..6d688e9b7 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowRatingBarTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowRatingBarTest.java
@@ -2,16 +2,17 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.widget.RatingBar;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowRatingBarTest {
private RatingBar ratingBar;
@@ -20,7 +21,7 @@ public class ShadowRatingBarTest {
@Before
public void setup() {
- ratingBar = new RatingBar(RuntimeEnvironment.application);
+ ratingBar = new RatingBar((Application) ApplicationProvider.getApplicationContext());
listener = new TestRatingBarChangedListener();
transcript = new ArrayList<>();
ratingBar.setOnRatingBarChangeListener(listener);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowRectTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowRectTest.java
index feed080d7..37951fd84 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowRectTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowRectTest.java
@@ -3,12 +3,12 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.graphics.Rect;
+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 ShadowRectTest {
@Before
public void setUp() {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowRelativeLayoutTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowRelativeLayoutTest.java
index a25819a14..03560ea8b 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowRelativeLayoutTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowRelativeLayoutTest.java
@@ -4,23 +4,25 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
+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;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowRelativeLayoutTest {
@Test
@Config(minSdk = JELLY_BEAN_MR1)
public void getRules_shouldShowAddRuleData_sinceApiLevel17() throws Exception {
- ImageView imageView = new ImageView(RuntimeEnvironment.application);
- RelativeLayout layout = new RelativeLayout(RuntimeEnvironment.application);
+ ImageView imageView = new ImageView((Application) ApplicationProvider.getApplicationContext());
+ RelativeLayout layout =
+ new RelativeLayout((Application) ApplicationProvider.getApplicationContext());
layout.addView(imageView, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) imageView.getLayoutParams();
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
@@ -32,8 +34,9 @@ public class ShadowRelativeLayoutTest {
@Test
@Config(maxSdk = JELLY_BEAN)
public void getRules_shouldShowAddRuleData_uptoApiLevel16() throws Exception {
- ImageView imageView = new ImageView(RuntimeEnvironment.application);
- RelativeLayout layout = new RelativeLayout(RuntimeEnvironment.application);
+ ImageView imageView = new ImageView((Application) ApplicationProvider.getApplicationContext());
+ RelativeLayout layout =
+ new RelativeLayout((Application) ApplicationProvider.getApplicationContext());
layout.addView(imageView, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) imageView.getLayoutParams();
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowRemoteCallbackListTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowRemoteCallbackListTest.java
index 8ea9c1e53..d75330c59 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowRemoteCallbackListTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowRemoteCallbackListTest.java
@@ -6,11 +6,11 @@ import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.RemoteCallbackList;
+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 ShadowRemoteCallbackListTest {
@Test
public void testBasicWiring() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowRenderNodeAnimatorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowRenderNodeAnimatorTest.java
index 12cf2cc86..b2db7f070 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowRenderNodeAnimatorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowRenderNodeAnimatorTest.java
@@ -9,14 +9,14 @@ import android.app.Activity;
import android.os.Build;
import android.view.View;
import android.view.ViewAnimationUtils;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowRenderNodeAnimatorTest {
private Activity activity;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowResolveInfoTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowResolveInfoTest.java
index 822b16f81..4bfde61e1 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowResolveInfoTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowResolveInfoTest.java
@@ -3,13 +3,13 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.content.pm.ResolveInfo;
+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.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowResolveInfoTest {
private ResolveInfo mResolveInfo;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowResourcesTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowResourcesTest.java
index 09a54df5f..d6095845e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowResourcesTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowResourcesTest.java
@@ -4,6 +4,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assume.assumeTrue;
import static org.robolectric.shadows.ShadowAssetManager.useLegacy;
+import android.app.Application;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
@@ -12,6 +13,8 @@ import android.os.Build;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.util.Xml;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.Range;
import java.io.InputStream;
import org.junit.Before;
@@ -19,27 +22,17 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.XmlResourceParserImpl;
import org.robolectric.annotation.Config;
import org.xmlpull.v1.XmlPullParser;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowResourcesTest {
private Resources resources;
@Before
public void setup() throws Exception {
- resources = RuntimeEnvironment.application.getResources();
- }
-
- @Test
- public void getQuantityString() throws Exception {
- assertThat(resources.getQuantityString(R.plurals.beer, 0)).isEqualTo("beers");
- assertThat(resources.getQuantityString(R.plurals.beer, 1)).isEqualTo("beer");
- assertThat(resources.getQuantityString(R.plurals.beer, 2)).isEqualTo("beers");
- assertThat(resources.getQuantityString(R.plurals.beer, 3)).isEqualTo("beers");
+ resources = ((Application) ApplicationProvider.getApplicationContext()).getResources();
}
@Test
@@ -180,10 +173,14 @@ public class ShadowResourcesTest {
.addAttribute(android.R.attr.viewportHeight, "24.0")
.build();
- TypedArray typedArray = RuntimeEnvironment.application.getTheme().obtainStyledAttributes(attributes, new int[] {
- android.R.attr.viewportWidth,
- android.R.attr.viewportHeight
- }, 0, 0);
+ TypedArray typedArray =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getTheme()
+ .obtainStyledAttributes(
+ attributes,
+ new int[] {android.R.attr.viewportWidth, android.R.attr.viewportHeight},
+ 0,
+ 0);
assertThat(typedArray.getFloat(0, 0)).isEqualTo(12.0f);
assertThat(typedArray.getFloat(1, 0)).isEqualTo(24.0f);
typedArray.recycle();
@@ -205,10 +202,14 @@ public class ShadowResourcesTest {
.addAttribute(android.R.attr.viewportHeight, "@dimen/dimen30px")
.build();
- TypedArray typedArray = RuntimeEnvironment.application.getTheme().obtainStyledAttributes(attributes, new int[] {
- android.R.attr.viewportWidth,
- android.R.attr.viewportHeight
- }, 0, 0);
+ TypedArray typedArray =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getTheme()
+ .obtainStyledAttributes(
+ attributes,
+ new int[] {android.R.attr.viewportWidth, android.R.attr.viewportHeight},
+ 0,
+ 0);
assertThat(typedArray.getDimension(0, 0)).isEqualTo(20f);
assertThat(typedArray.getDimension(1, 0)).isEqualTo(30f);
typedArray.recycle();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowRestrictionsManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowRestrictionsManagerTest.java
index 4596a57c7..4a5a414f5 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowRestrictionsManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowRestrictionsManagerTest.java
@@ -4,19 +4,20 @@ import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.content.RestrictionEntry;
import android.content.RestrictionsManager;
import android.os.Bundle;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.Iterables;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public final class ShadowRestrictionsManagerTest {
@@ -25,7 +26,7 @@ public final class ShadowRestrictionsManagerTest {
@Before
public void setUp() {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
restrictionsManager = (RestrictionsManager) context.getSystemService(Context.RESTRICTIONS_SERVICE);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowResultReceiverTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowResultReceiverTest.java
index 30a1fc60c..e0d1f2180 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowResultReceiverTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowResultReceiverTest.java
@@ -5,11 +5,11 @@ import static org.junit.Assert.assertEquals;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
+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 ShadowResultReceiverTest {
@Test
public void callingSend_shouldCallOverridenOnReceiveResultWithTheSameArguments() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSQLiteConnectionTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSQLiteConnectionTest.java
index 55ece15ff..257b6deb8 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSQLiteConnectionTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSQLiteConnectionTest.java
@@ -5,11 +5,14 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.robolectric.shadows.ShadowSQLiteConnection.convertSQLWithLocalizedUnicodeCollator;
+import android.app.Application;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatatypeMismatchException;
import android.database.sqlite.SQLiteStatement;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.almworks.sqlite4java.SQLiteConnection;
import java.io.File;
import java.util.ArrayList;
@@ -20,12 +23,10 @@ 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;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowSQLiteConnectionTest {
private SQLiteDatabase database;
@@ -33,7 +34,7 @@ public class ShadowSQLiteConnectionTest {
private long ptr;
private SQLiteConnection conn;
private ShadowSQLiteConnection.Connections CONNECTIONS;
-
+
@Before
public void setUp() throws Exception {
database = createDatabase("database.db");
@@ -55,7 +56,7 @@ public class ShadowSQLiteConnectionTest {
assertThat(convertSQLWithLocalizedUnicodeCollator(
"select * from `routine` order by name \n\r \f collate\f\n\tunicode"
- + "\n, id \n\n\t collate\n\t \n\flocalized"))
+ + "\n, id \n\n\t collate\n\t \n\flocalized"))
.isEqualTo("select * from `routine` order by name COLLATE NOCASE\n"
+ ", id COLLATE NOCASE");
@@ -96,13 +97,13 @@ public class ShadowSQLiteConnectionTest {
assertThat(conn).isNotNull();
assertThat(conn.isOpen()).named("open").isTrue();
}
-
+
@Test
public void nativeClose_closesConnection() {
ShadowSQLiteConnection.nativeClose(ptr);
assertThat(conn.isOpen()).named("open").isFalse();
}
-
+
@Test
public void reset_closesConnection() {
ShadowSQLiteConnection.reset();
@@ -118,7 +119,7 @@ public class ShadowSQLiteConnectionTest {
assertThat(connectionsMap).named("connections after").isEmpty();
}
-
+
@Test
public void reset_clearsStatementCache() {
final Map<Long, SQLiteStatement> statementsMap = ReflectionHelpers.getField(CONNECTIONS, "statementsMap");
@@ -167,7 +168,8 @@ public class ShadowSQLiteConnectionTest {
}
private SQLiteDatabase createDatabase(String filename) {
- databasePath = RuntimeEnvironment.application.getDatabasePath(filename);
+ databasePath =
+ ((Application) ApplicationProvider.getApplicationContext()).getDatabasePath(filename);
databasePath.getParentFile().mkdirs();
return SQLiteDatabase.openOrCreateDatabase(databasePath.getPath(), null);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowScaleGestureDetectorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowScaleGestureDetectorTest.java
index e407fd6f1..51e11b9d5 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowScaleGestureDetectorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowScaleGestureDetectorTest.java
@@ -5,15 +5,16 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
+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 ShadowScaleGestureDetectorTest {
private ScaleGestureDetector detector;
@@ -21,7 +22,8 @@ public class ShadowScaleGestureDetectorTest {
@Before
public void setUp() throws Exception {
- detector = new ScaleGestureDetector(RuntimeEnvironment.application, null);
+ detector =
+ new ScaleGestureDetector((Application) ApplicationProvider.getApplicationContext(), null);
motionEvent = MotionEvent.obtain(-1, -1, MotionEvent.ACTION_UP, 100, 30, -1);
}
@@ -47,7 +49,12 @@ public class ShadowScaleGestureDetectorTest {
@Test
public void test_getListener() throws Exception {
TestOnGestureListener listener = new TestOnGestureListener();
- assertSame(listener, shadowOf(new ScaleGestureDetector(RuntimeEnvironment.application, listener)).getListener());
+ assertSame(
+ listener,
+ shadowOf(
+ new ScaleGestureDetector(
+ (Application) ApplicationProvider.getApplicationContext(), listener))
+ .getListener());
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowScanResultTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowScanResultTest.java
index 963abc2da..4670e9736 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowScanResultTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowScanResultTest.java
@@ -5,11 +5,11 @@ import static org.junit.Assert.assertNotNull;
import static org.robolectric.Shadows.shadowOf;
import android.net.wifi.ScanResult;
+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 ShadowScanResultTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowScrollViewTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowScrollViewTest.java
index 984cbf4c3..c5819aa05 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowScrollViewTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowScrollViewTest.java
@@ -2,17 +2,19 @@ package org.robolectric.shadows;
import static org.junit.Assert.assertEquals;
+import android.app.Application;
import android.widget.ScrollView;
+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 ShadowScrollViewTest {
@Test
public void shouldSmoothScrollTo() throws Exception {
- ScrollView scrollView = new ScrollView(RuntimeEnvironment.application);
+ ScrollView scrollView =
+ new ScrollView((Application) ApplicationProvider.getApplicationContext());
scrollView.smoothScrollTo(7, 6);
assertEquals(7, scrollView.getScrollX());
@@ -21,7 +23,8 @@ public class ShadowScrollViewTest {
@Test
public void shouldSmoothScrollBy() throws Exception {
- ScrollView scrollView = new ScrollView(RuntimeEnvironment.application);
+ ScrollView scrollView =
+ new ScrollView((Application) ApplicationProvider.getApplicationContext());
scrollView.smoothScrollTo(7, 6);
scrollView.smoothScrollBy(10, 20);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowScrollerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowScrollerTest.java
index 38680427c..d529ec9da 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowScrollerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowScrollerTest.java
@@ -2,21 +2,24 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.view.animation.BounceInterpolator;
import android.widget.Scroller;
+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 ShadowScrollerTest {
private Scroller scroller;
@Before
public void setup() throws Exception {
- scroller = new Scroller(RuntimeEnvironment.application, new BounceInterpolator());
+ scroller =
+ new Scroller(
+ (Application) ApplicationProvider.getApplicationContext(), new BounceInterpolator());
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSeekBarTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSeekBarTest.java
index f54caa3d2..9b2ae36b9 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSeekBarTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSeekBarTest.java
@@ -2,17 +2,18 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.widget.SeekBar;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowSeekBarTest {
private SeekBar seekBar;
@@ -22,7 +23,7 @@ public class ShadowSeekBarTest {
@Before
public void setup() {
- seekBar = new SeekBar(RuntimeEnvironment.application);
+ seekBar = new SeekBar((Application) ApplicationProvider.getApplicationContext());
shadow = Shadows.shadowOf(seekBar);
listener = new TestSeekBarChangedListener();
transcript = new ArrayList<>();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSensorManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSensorManagerTest.java
index 801bf5a1b..f1b7068b2 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSensorManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSensorManagerTest.java
@@ -4,6 +4,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorDirectChannel;
@@ -12,16 +13,16 @@ import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.MemoryFile;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.base.Optional;
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;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowSensorManagerTest {
private SensorManager sensorManager;
@@ -29,7 +30,10 @@ public class ShadowSensorManagerTest {
@Before
public void setUp() {
- sensorManager = (SensorManager) RuntimeEnvironment.application.getSystemService(Context.SENSOR_SERVICE);
+ sensorManager =
+ (SensorManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.SENSOR_SERVICE);
shadow = shadowOf(sensorManager);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSensorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSensorTest.java
index 5c63c864e..0afe67462 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSensorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSensorTest.java
@@ -4,15 +4,13 @@ import static com.google.common.truth.Truth.assertThat;
import android.hardware.Sensor;
import android.os.Build;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-/**
- * Test for {@link ShadowSensor}
- */
-@RunWith(RobolectricTestRunner.class)
+/** Test for {@link ShadowSensor} */
+@RunWith(AndroidJUnit4.class)
public class ShadowSensorTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowServiceTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowServiceTest.java
index 8f65685b1..1fb085cdc 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowServiceTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowServiceTest.java
@@ -3,6 +3,7 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
@@ -11,22 +12,25 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.media.MediaScannerConnection;
import android.os.IBinder;
+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.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowServiceTest {
private MyService service ;
private ShadowService shadow;
private Notification.Builder notBuilder;
- private final ShadowNotificationManager nm = shadowOf((NotificationManager) RuntimeEnvironment.application
- .getSystemService(Context.NOTIFICATION_SERVICE));
+ private final ShadowNotificationManager nm =
+ shadowOf(
+ (NotificationManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.NOTIFICATION_SERVICE));
@Before
public void setup() {
@@ -40,7 +44,8 @@ public class ShadowServiceTest {
@Test
public void shouldUnbindServiceAtShadowApplication() {
- ShadowApplication shadowApplication = shadowOf(RuntimeEnvironment.application);
+ ShadowApplication shadowApplication =
+ shadowOf((Application) ApplicationProvider.getApplicationContext());
ServiceConnection conn = Shadow.newInstanceOf(MediaScannerConnection.class);
service.bindService(new Intent("dummy"), conn, 0);
assertThat(shadowApplication.getUnboundServiceConnections()).isEmpty();
@@ -121,6 +126,12 @@ public class ShadowServiceTest {
assertThat(shadow.isStoppedBySelf()).isTrue();
}
+ @Test
+ public void shouldStopSelfResultWithId() {
+ service.stopSelfResult(1);
+ assertThat(shadow.isStoppedBySelf()).isTrue();
+ }
+
public static class MyService extends Service {
@Override
public void onDestroy() {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSettingsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSettingsTest.java
index 6b61c7af5..4ae9d3667 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSettingsTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSettingsTest.java
@@ -3,124 +3,210 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.content.ContentResolver;
import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.provider.Settings.Secure;
import android.text.format.DateFormat;
+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;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowSettingsTest {
private ContentResolver contentResolver;
@Before
- public void setUp() {
- contentResolver = RuntimeEnvironment.application.getContentResolver();
+ public void setUp() throws Exception {
+ contentResolver =
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver();
}
@Test
- public void testSystemGetInt() {
+ public void testSystemGetInt() throws Exception {
assertThat(Settings.System.getInt(contentResolver, "property", 0)).isEqualTo(0);
assertThat(Settings.System.getInt(contentResolver, "property", 2)).isEqualTo(2);
Settings.System.putInt(contentResolver, "property", 1);
assertThat(Settings.System.getInt(contentResolver, "property", 0)).isEqualTo(1);
-
- Settings.System.putString(contentResolver, "property", "11");
- assertThat(Settings.System.getInt(contentResolver, "property", 0)).isEqualTo(11);
}
@Test
- public void testSecureGetInt() {
+ public void testSecureGetInt() throws Exception {
assertThat(Settings.Secure.getInt(contentResolver, "property", 0)).isEqualTo(0);
assertThat(Settings.Secure.getInt(contentResolver, "property", 2)).isEqualTo(2);
Settings.Secure.putInt(contentResolver, "property", 1);
assertThat(Settings.Secure.getInt(contentResolver, "property", 0)).isEqualTo(1);
-
- Settings.Secure.putString(contentResolver, "property", "11");
- assertThat(Settings.Secure.getInt(contentResolver, "property", 0)).isEqualTo(11);
}
@Test
@Config(minSdk = JELLY_BEAN_MR1)
- public void testGlobalGetInt() {
+ public void testGlobalGetInt() throws Exception {
assertThat(Settings.Global.getInt(contentResolver, "property", 0)).isEqualTo(0);
assertThat(Settings.Global.getInt(contentResolver, "property", 2)).isEqualTo(2);
Settings.Global.putInt(contentResolver, "property", 1);
assertThat(Settings.Global.getInt(contentResolver, "property", 0)).isEqualTo(1);
-
- Settings.Global.putString(contentResolver, "property", "11");
- assertThat(Settings.Global.getInt(contentResolver, "property", 0)).isEqualTo(11);
}
@Test
- public void testSystemGetString() {
+ public void testSystemGetString() throws Exception {
assertThat(Settings.System.getString(contentResolver, "property")).isNull();
Settings.System.putString(contentResolver, "property", "value");
assertThat(Settings.System.getString(contentResolver, "property")).isEqualTo("value");
-
- Settings.System.putInt(contentResolver, "property", 123);
- assertThat(Settings.System.getString(contentResolver, "property")).isEqualTo("123");
-
- Settings.System.putLong(contentResolver, "property", 456L);
- assertThat(Settings.System.getString(contentResolver, "property")).isEqualTo("456");
-
- Settings.System.putFloat(contentResolver, "property", 7.89f);
- assertThat(Settings.System.getString(contentResolver, "property")).isEqualTo("7.89");
}
@Test
- public void testSystemGetLong() throws Settings.SettingNotFoundException {
+ public void testSystemGetLong() throws Exception {
assertThat(Settings.System.getLong(contentResolver, "property", 10L)).isEqualTo(10L);
Settings.System.putLong(contentResolver, "property", 42L);
assertThat(Settings.System.getLong(contentResolver, "property")).isEqualTo(42L);
assertThat(Settings.System.getLong(contentResolver, "property", 10L)).isEqualTo(42L);
-
- Settings.System.putString(contentResolver, "property", "11");
- assertThat(Settings.System.getLong(contentResolver, "property", 0)).isEqualTo(11L);
}
@Test
- public void testSystemGetFloat() {
+ public void testSystemGetFloat() throws Exception {
assertThat(Settings.System.getFloat(contentResolver, "property", 23.23f)).isEqualTo(23.23f);
Settings.System.putFloat(contentResolver, "property", 42.42f);
assertThat(Settings.System.getFloat(contentResolver, "property", 10L)).isEqualTo(42.42f);
-
- Settings.System.putString(contentResolver, "property", "11.2");
- assertThat(Settings.System.getFloat(contentResolver, "property", 0)).isEqualTo(11.2f);
}
@Test(expected = Settings.SettingNotFoundException.class)
- public void testSystemGetLong_exception() throws Settings.SettingNotFoundException {
+ public void testSystemGetLong_exception() throws Exception {
Settings.System.getLong(contentResolver, "property");
}
@Test(expected = Settings.SettingNotFoundException.class)
- public void testSystemGetInt_exception() throws Settings.SettingNotFoundException {
+ public void testSystemGetInt_exception() throws Exception {
Settings.System.getInt(contentResolver, "property");
}
@Test(expected = Settings.SettingNotFoundException.class)
- public void testSystemGetFloat_exception() throws Settings.SettingNotFoundException {
+ public void testSystemGetFloat_exception() throws Exception {
Settings.System.getFloat(contentResolver, "property");
}
@Test
public void testSet24HourMode_24() {
ShadowSettings.set24HourTimeFormat(true);
- assertThat(DateFormat.is24HourFormat(RuntimeEnvironment.application)).isTrue();
+ assertThat(
+ DateFormat.is24HourFormat(
+ ((Application) ApplicationProvider.getApplicationContext()).getBaseContext()))
+ .isTrue();
}
@Test
public void testSet24HourMode_12() {
ShadowSettings.set24HourTimeFormat(false);
- assertThat(DateFormat.is24HourFormat(RuntimeEnvironment.application)).isFalse();
+ assertThat(
+ DateFormat.is24HourFormat(
+ ((Application) ApplicationProvider.getApplicationContext()).getBaseContext()))
+ .isFalse();
+ }
+
+ @Test
+ public void testSetAdbEnabled_settingsSecure_true() {
+ ShadowSettings.setAdbEnabled(true);
+
+ assertThat(
+ Secure.getInt(
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver(),
+ Secure.ADB_ENABLED,
+ /* def= */ 0))
+ .isEqualTo(1);
+ }
+
+ @Test
+ public void testSetAdbEnabled_settingsSecure_false() {
+ ShadowSettings.setAdbEnabled(false);
+
+ assertThat(
+ Secure.getInt(
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver(),
+ Secure.ADB_ENABLED,
+ /* def= */ 1))
+ .isEqualTo(0);
+ }
+
+ @Test
+ @Config(minSdk = JELLY_BEAN_MR1)
+ public void testSetAdbEnabled_sinceJBMR1_settingsGlobal_true() {
+ ShadowSettings.setAdbEnabled(true);
+
+ assertThat(
+ Global.getInt(
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver(),
+ Global.ADB_ENABLED,
+ /* def= */ 0))
+ .isEqualTo(1);
+ }
+
+ @Test
+ @Config(minSdk = JELLY_BEAN_MR1)
+ public void testSetAdbEnabled_sinceJBMR1_settingsGlobal_false() {
+ ShadowSettings.setAdbEnabled(false);
+
+ assertThat(
+ Global.getInt(
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver(),
+ Global.ADB_ENABLED,
+ /* def= */ 1))
+ .isEqualTo(0);
+ }
+
+ @Test
+ public void testSetInstallNonMarketApps_settingsSecure_true() {
+ ShadowSettings.setInstallNonMarketApps(true);
+
+ assertThat(
+ Secure.getInt(
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver(),
+ Secure.INSTALL_NON_MARKET_APPS,
+ /* def= */ 0))
+ .isEqualTo(1);
+ }
+
+ @Test
+ public void testSetInstallNonMarketApps_settingsSecure_false() {
+ ShadowSettings.setInstallNonMarketApps(false);
+
+ assertThat(
+ Secure.getInt(
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver(),
+ Secure.INSTALL_NON_MARKET_APPS,
+ /* def= */ 1))
+ .isEqualTo(0);
+ }
+
+ @Test
+ @Config(minSdk = JELLY_BEAN_MR1)
+ public void testSetInstallNonMarketApps_sinceJBMR1_settingsGlobal_true() {
+ ShadowSettings.setInstallNonMarketApps(true);
+
+ assertThat(
+ Global.getInt(
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver(),
+ Global.INSTALL_NON_MARKET_APPS,
+ /* def= */ 0))
+ .isEqualTo(1);
+ }
+
+ @Test
+ @Config(minSdk = JELLY_BEAN_MR1)
+ public void testSetInstallNonMarketApps_sinceJBMR1_settingsGlobal_false() {
+ ShadowSettings.setInstallNonMarketApps(false);
+
+ assertThat(
+ Global.getInt(
+ ((Application) ApplicationProvider.getApplicationContext()).getContentResolver(),
+ Global.INSTALL_NON_MARKET_APPS,
+ /* def= */ 1))
+ .isEqualTo(0);
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowShapeDrawableTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowShapeDrawableTest.java
index ca4ce3dc1..ca02d623c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowShapeDrawableTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowShapeDrawableTest.java
@@ -5,11 +5,11 @@ import static org.junit.Assert.assertNotNull;
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
+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 ShadowShapeDrawableTest {
@Test
public void getPaint_ShouldReturnTheSamePaint() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSharedMemoryTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSharedMemoryTest.java
index 4e6011239..40bc27603 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSharedMemoryTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSharedMemoryTest.java
@@ -4,15 +4,13 @@ import static com.google.common.truth.Truth.assertThat;
import android.os.Build;
import android.os.SharedMemory;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-/**
- * Unit tests for {@link ShadowSharedMemory}.
- */
-@RunWith(RobolectricTestRunner.class)
+/** Unit tests for {@link ShadowSharedMemory}. */
+@RunWith(AndroidJUnit4.class)
public class ShadowSharedMemoryTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSharedPreferencesTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSharedPreferencesTest.java
index 13c653d60..0fed69109 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSharedPreferencesTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSharedPreferencesTest.java
@@ -6,9 +6,12 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyZeroInteractions;
+import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -16,10 +19,8 @@ import java.util.Set;
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 ShadowSharedPreferencesTest {
private final static String FILENAME = "filename";
private SharedPreferences.Editor editor;
@@ -31,7 +32,7 @@ public class ShadowSharedPreferencesTest {
@Before
public void setUp() {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
sharedPreferences = context.getSharedPreferences(FILENAME, Context.MODE_PRIVATE);
// Ensure no shared preferences have leaked from previous tests.
@@ -208,4 +209,18 @@ public class ShadowSharedPreferencesTest {
String restored = anotherSharedPreferences.getString("foo", null);
assertThat(restored).isEqualTo("bar");
}
+
+ /**
+ * Tests a sequence of operations in SharedPrefereces that would previously cause a deadlock.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void commit_multipleTimes() throws Exception {
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ sharedPreferences.edit().putBoolean("foo", true).apply();
+ sharedPreferences.edit().putBoolean("bar", true).commit();
+ assertTrue(sharedPreferences.getBoolean("foo", false));
+ assertTrue(sharedPreferences.getBoolean("bar", false));
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowShortcutManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowShortcutManagerTest.java
index f7f0f6c1f..fcc36b1b9 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowShortcutManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowShortcutManagerTest.java
@@ -4,29 +4,32 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import android.app.Application;
import android.content.Context;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.os.Build;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
/** Unit tests for ShadowShortcutManager. */
@Config(minSdk = Build.VERSION_CODES.N_MR1)
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public final class ShadowShortcutManagerTest {
private ShortcutManager shortcutManager;
@Before
public void setUp() {
shortcutManager =
- (ShortcutManager) RuntimeEnvironment.application.getSystemService(Context.SHORTCUT_SERVICE);
+ (ShortcutManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.SHORTCUT_SERVICE);
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSimpleCursorAdapterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSimpleCursorAdapterTest.java
index fd1a17f55..6b2e4d55e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSimpleCursorAdapterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSimpleCursorAdapterTest.java
@@ -2,20 +2,28 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.widget.SimpleCursorAdapter;
+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 ShadowSimpleCursorAdapterTest {
@Test
public void testChangeCursor() {
- SimpleCursorAdapter adapter = new SimpleCursorAdapter(RuntimeEnvironment.application, 1, null, new String[]{"name"}, new int[]{2}, 0);
+ SimpleCursorAdapter adapter =
+ new SimpleCursorAdapter(
+ (Application) ApplicationProvider.getApplicationContext(),
+ 1,
+ null,
+ new String[] {"name"},
+ new int[] {2},
+ 0);
Cursor cursor = setUpDatabase();
@@ -26,7 +34,14 @@ public class ShadowSimpleCursorAdapterTest {
@Test
public void testSwapCursor() {
- SimpleCursorAdapter adapter = new SimpleCursorAdapter(RuntimeEnvironment.application, 1, null, new String[]{"name"}, new int[]{2}, 0);
+ SimpleCursorAdapter adapter =
+ new SimpleCursorAdapter(
+ (Application) ApplicationProvider.getApplicationContext(),
+ 1,
+ null,
+ new String[] {"name"},
+ new int[] {2},
+ 0);
Cursor cursor = setUpDatabase();
@@ -37,7 +52,14 @@ public class ShadowSimpleCursorAdapterTest {
@Test
public void testSwapCursorToNull() {
- SimpleCursorAdapter adapter = new SimpleCursorAdapter(RuntimeEnvironment.application, 1, null, new String[]{"name"}, new int[]{2}, 0);
+ SimpleCursorAdapter adapter =
+ new SimpleCursorAdapter(
+ (Application) ApplicationProvider.getApplicationContext(),
+ 1,
+ null,
+ new String[] {"name"},
+ new int[] {2},
+ 0);
Cursor cursor = setUpDatabase();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSliceManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSliceManagerTest.java
new file mode 100644
index 000000000..22ec514de
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSliceManagerTest.java
@@ -0,0 +1,71 @@
+package org.robolectric.shadows;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.app.slice.SliceManager;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build.VERSION_CODES;
+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.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+/** Tests for {@link ShadowSliceManager}. */
+@RunWith(AndroidJUnit4.class)
+@Config(minSdk = VERSION_CODES.P)
+public final class ShadowSliceManagerTest {
+
+ private static final String PACKAGE_NAME_1 = "com.google.testing.slicemanager.foo";
+ private static final int PACKAGE_1_UID = 10;
+ private Uri sliceUri1;
+ private static final String PACKAGE_NAME_2 = "com.google.testing.slicemanager.bar";
+ private static final int PACKAGE_2_UID = 20;
+ private Uri sliceUri2;
+ private SliceManager sliceManager;
+
+ @Before
+ public void setUp() {
+ PackageManager packageManager = RuntimeEnvironment.application.getPackageManager();
+ ShadowApplicationPackageManager shadowPackageManager =
+ (ShadowApplicationPackageManager) shadowOf(packageManager);
+ shadowPackageManager.setPackagesForUid(PACKAGE_1_UID, new String[] {PACKAGE_NAME_1});
+ shadowPackageManager.setPackagesForUid(PACKAGE_2_UID, new String[] {PACKAGE_NAME_2});
+ sliceUri1 = Uri.parse("content://a/b");
+ sliceUri2 = Uri.parse("content://c/d");
+ sliceManager = ApplicationProvider.getApplicationContext().getSystemService(SliceManager.class);
+ }
+
+ @Test
+ public void testGrantSlicePermission_grantsPermissionToPackage() {
+ sliceManager.grantSlicePermission(PACKAGE_NAME_1, sliceUri1);
+ assertThat(sliceManager.checkSlicePermission(sliceUri1, /* pid= */ 1, PACKAGE_1_UID))
+ .isEqualTo(PackageManager.PERMISSION_GRANTED);
+ }
+
+ @Test
+ public void testGrantSlicePermission_doesNotGrantPermissionToOtherPackage() {
+ sliceManager.grantSlicePermission(PACKAGE_NAME_1, sliceUri1);
+ assertThat(sliceManager.checkSlicePermission(sliceUri1, /* pid= */ 1, PACKAGE_2_UID))
+ .isEqualTo(PackageManager.PERMISSION_DENIED);
+ }
+
+ @Test
+ public void testGrantSlicePermission_doesNotGrantPermissionToOtherSliceUri() {
+ sliceManager.grantSlicePermission(PACKAGE_NAME_1, sliceUri1);
+ assertThat(sliceManager.checkSlicePermission(sliceUri2, /* pid= */ 1, PACKAGE_1_UID))
+ .isEqualTo(PackageManager.PERMISSION_DENIED);
+ }
+
+ @Test
+ public void testRevokeSlicePermission_revokesPermissionToPackage() {
+ sliceManager.grantSlicePermission(PACKAGE_NAME_1, sliceUri1);
+ sliceManager.revokeSlicePermission(PACKAGE_NAME_1, sliceUri1);
+ assertThat(sliceManager.checkSlicePermission(sliceUri1, /* pid= */ 1, PACKAGE_1_UID))
+ .isEqualTo(PackageManager.PERMISSION_DENIED);
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSmsManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSmsManagerTest.java
index 93fb2795d..a7ff59f41 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSmsManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSmsManagerTest.java
@@ -5,16 +5,17 @@ import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.PendingIntent;
import android.telephony.SmsManager;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.collect.Lists;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = JELLY_BEAN_MR2)
public class ShadowSmsManagerTest {
private SmsManager smsManager = SmsManager.getDefault();
@@ -78,8 +79,12 @@ public class ShadowSmsManagerTest {
public void sendDataMessage_shouldStoreLastParameters() {
final short destPort = 24;
final byte[] data = new byte[]{0, 1, 2, 3, 4};
- final PendingIntent sentIntent = PendingIntent.getActivity(RuntimeEnvironment.application, 10, null, 0);
- final PendingIntent deliveryIntent = PendingIntent.getActivity(RuntimeEnvironment.application, 10, null, 0);
+ final PendingIntent sentIntent =
+ PendingIntent.getActivity(
+ (Application) ApplicationProvider.getApplicationContext(), 10, null, 0);
+ final PendingIntent deliveryIntent =
+ PendingIntent.getActivity(
+ (Application) ApplicationProvider.getApplicationContext(), 10, null, 0);
smsManager.sendDataMessage(destAddress, scAddress, destPort, data, sentIntent, deliveryIntent);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSoundPoolTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSoundPoolTest.java
index ca2998a6f..bc47871a4 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSoundPoolTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSoundPoolTest.java
@@ -4,18 +4,21 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.robolectric.Shadows.shadowOf;
import android.media.AudioManager;
import android.media.SoundPool;
+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.R;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowSoundPool.Playback;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowSoundPoolTest {
@Test
@@ -39,10 +42,25 @@ public class ShadowSoundPoolTest {
public void playedSoundsFromResourcesAreRecorded() {
SoundPool soundPool = createSoundPool();
- int soundId = soundPool.load(RuntimeEnvironment.application, R.raw.sound, 1);
+ int soundId = soundPool.load(ApplicationProvider.getApplicationContext(), R.raw.sound, 1);
soundPool.play(soundId, 1.0f, 1.0f, 1, 0, 1);
- assertThat(Shadows.shadowOf(soundPool).wasResourcePlayed(R.raw.sound)).isTrue();
+ assertThat(shadowOf(soundPool).wasResourcePlayed(R.raw.sound)).isTrue();
+ }
+
+ @Test
+ public void playedSoundsFromResourcesAreCollected() {
+ SoundPool soundPool = createSoundPool();
+
+ int soundId = soundPool.load(ApplicationProvider.getApplicationContext(), R.raw.sound, 1);
+ soundPool.play(soundId, 1.0f, 0f, 0, 0, 0.5f);
+ soundPool.play(soundId, 0f, 1.0f, 1, 0, 2.0f);
+
+ assertThat(shadowOf(soundPool).getResourcePlaybacks(R.raw.sound))
+ .containsExactly(
+ new Playback(soundId, 1.0f, 0f, 0, 0, 0.5f),
+ new Playback(soundId, 0f, 1.0f, 1, 0, 2.0f))
+ .inOrder();
}
@Test
@@ -52,19 +70,92 @@ public class ShadowSoundPoolTest {
int soundId = soundPool.load("/mnt/sdcard/sound.wav", 1);
soundPool.play(soundId, 1.0f, 1.0f, 1, 0, 1);
- assertThat(Shadows.shadowOf(soundPool).wasPathPlayed("/mnt/sdcard/sound.wav")).isTrue();
+ assertThat(shadowOf(soundPool).wasPathPlayed("/mnt/sdcard/sound.wav")).isTrue();
+ }
+
+ @Test
+ public void playedSoundsFromPathAreCollected() {
+ SoundPool soundPool = createSoundPool();
+
+ int soundId = soundPool.load("/mnt/sdcard/sound.wav", 1);
+ soundPool.play(soundId, 0f, 1.0f, 1, 0, 2.0f);
+ soundPool.play(soundId, 1.0f, 0f, 0, 0, 0.5f);
+
+ assertThat(shadowOf(soundPool).getPathPlaybacks("/mnt/sdcard/sound.wav"))
+ .containsExactly(
+ new Playback(soundId, 0f, 1.0f, 1, 0, 2.0f),
+ new Playback(soundId, 1.0f, 0f, 0, 0, 0.5f))
+ .inOrder();
+ }
+
+ @Test
+ public void notifyPathLoaded_notifiesListener() {
+ SoundPool soundPool = createSoundPool();
+ SoundPool.OnLoadCompleteListener listener = mock(SoundPool.OnLoadCompleteListener.class);
+ soundPool.setOnLoadCompleteListener(listener);
+
+ int soundId = soundPool.load("/mnt/sdcard/sound.wav", 1);
+ shadowOf(soundPool).notifyPathLoaded("/mnt/sdcard/sound.wav", true);
+
+ verify(listener).onLoadComplete(soundPool, soundId, 0);
+ }
+
+ @Test
+ public void notifyResourceLoaded_notifiesListener() {
+ SoundPool soundPool = createSoundPool();
+ SoundPool.OnLoadCompleteListener listener = mock(SoundPool.OnLoadCompleteListener.class);
+ soundPool.setOnLoadCompleteListener(listener);
+
+ int soundId = soundPool.load(ApplicationProvider.getApplicationContext(), R.raw.sound, 1);
+ shadowOf(soundPool).notifyResourceLoaded(R.raw.sound, true);
+
+ verify(listener).onLoadComplete(soundPool, soundId, 0);
+ }
+
+ @Test
+ public void notifyPathLoaded_notifiesFailure() {
+ SoundPool soundPool = createSoundPool();
+ SoundPool.OnLoadCompleteListener listener = mock(SoundPool.OnLoadCompleteListener.class);
+ soundPool.setOnLoadCompleteListener(listener);
+
+ int soundId = soundPool.load("/mnt/sdcard/sound.wav", 1);
+ shadowOf(soundPool).notifyPathLoaded("/mnt/sdcard/sound.wav", false);
+
+ verify(listener).onLoadComplete(soundPool, soundId, 1);
+ }
+
+ @Test
+ public void notifyResourceLoaded_doNotFailWithoutListener() {
+ SoundPool soundPool = createSoundPool();
+
+ soundPool.load("/mnt/sdcard/sound.wav", 1);
+ shadowOf(soundPool).notifyPathLoaded("/mnt/sdcard/sound.wav", false);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void notifyPathLoaded_failIfLoadWasntCalled() {
+ SoundPool soundPool = createSoundPool();
+
+ shadowOf(soundPool).notifyPathLoaded("no.mp3", true);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void notifyResourceLoaded_failIfLoadWasntCalled() {
+ SoundPool soundPool = createSoundPool();
+
+ shadowOf(soundPool).notifyResourceLoaded(123, true);
}
@Test
public void playedSoundsAreCleared() {
SoundPool soundPool = createSoundPool();
- int soundId = soundPool.load(RuntimeEnvironment.application, R.raw.sound, 1);
+ int soundId = soundPool.load(ApplicationProvider.getApplicationContext(), R.raw.sound, 1);
soundPool.play(soundId, 1.0f, 1.0f, 1, 0, 1);
- assertThat(Shadows.shadowOf(soundPool).wasResourcePlayed(R.raw.sound)).isTrue();
- Shadows.shadowOf(soundPool).clearPlayed();
- assertThat(Shadows.shadowOf(soundPool).wasResourcePlayed(R.raw.sound)).isFalse();
+ assertThat(shadowOf(soundPool).wasResourcePlayed(R.raw.sound)).isTrue();
+ shadowOf(soundPool).clearPlayed();
+ assertThat(shadowOf(soundPool).wasResourcePlayed(R.raw.sound)).isFalse();
}
private SoundPool createSoundPool() {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSpannableStringTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSpannableStringTest.java
index e212fa65d..31443c1b2 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSpannableStringTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSpannableStringTest.java
@@ -5,12 +5,12 @@ import static com.google.common.truth.Truth.assertThat;
import android.text.SpannableString;
import android.text.style.URLSpan;
import android.text.style.UnderlineSpan;
+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 ShadowSpannableStringTest {
private static final String TEST_STRING = "Visit us at http://www.foobar.com for more selections";
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSpannedStringTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSpannedStringTest.java
index 49f7709ab..37f8fe4d8 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSpannedStringTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSpannedStringTest.java
@@ -4,11 +4,11 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import android.text.SpannedString;
+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 ShadowSpannedStringTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSslErrorHandlerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSslErrorHandlerTest.java
index 76cca4cea..31be9ab38 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSslErrorHandlerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSslErrorHandlerTest.java
@@ -3,14 +3,14 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.webkit.SslErrorHandler;
+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.Shadows;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowSslErrorHandlerTest {
private SslErrorHandler handler;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowStatFsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowStatFsTest.java
index 6763103ba..f58c440cf 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowStatFsTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowStatFsTest.java
@@ -4,13 +4,13 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
import static com.google.common.truth.Truth.assertThat;
import android.os.StatFs;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowStatFsTest {
@Test
public void shouldRegisterStats() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowStateListDrawableTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowStateListDrawableTest.java
index 950256ecd..c7ac37e2a 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowStateListDrawableTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowStateListDrawableTest.java
@@ -8,11 +8,11 @@ import android.R;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.util.StateSet;
+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 ShadowStateListDrawableTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowStaticLayoutTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowStaticLayoutTest.java
index 8e30ad14c..254db507e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowStaticLayoutTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowStaticLayoutTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
+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 ShadowStaticLayoutTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowStatusBarManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowStatusBarManagerTest.java
new file mode 100644
index 000000000..1a71c74de
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowStatusBarManagerTest.java
@@ -0,0 +1,60 @@
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.M;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.util.ReflectionHelpers;
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
+
+/** Unit tests for {@link ShadowStatusBarManager}. */
+@RunWith(AndroidJUnit4.class)
+public final class ShadowStatusBarManagerTest {
+
+ @Test
+ public void getDisable() throws ClassNotFoundException {
+ callDisableMethodofStatusBarManager(ShadowStatusBarManager.DEFAULT_DISABLE_MASK);
+ assertThat(
+ ((ShadowStatusBarManager)
+ Shadow.extract(
+ getApplicationContext().getSystemService(Context.STATUS_BAR_SERVICE)))
+ .getDisableFlags())
+ .isEqualTo(ShadowStatusBarManager.DEFAULT_DISABLE_MASK);
+ }
+
+ @Test
+ @Config(minSdk = M)
+ public void getDisable2() throws ClassNotFoundException {
+ callDisable2MethodofStatusBarManager(ShadowStatusBarManager.DEFAULT_DISABLE2_MASK);
+ assertThat(
+ ((ShadowStatusBarManager)
+ Shadow.extract(
+ getApplicationContext().getSystemService(Context.STATUS_BAR_SERVICE)))
+ .getDisable2Flags())
+ .isEqualTo(ShadowStatusBarManager.DEFAULT_DISABLE2_MASK);
+ }
+
+ private static void callDisableMethodofStatusBarManager(int disableFlags)
+ throws ClassNotFoundException {
+ ReflectionHelpers.callInstanceMethod(
+ Class.forName("android.app.StatusBarManager"),
+ getApplicationContext().getSystemService(Context.STATUS_BAR_SERVICE),
+ "disable",
+ ClassParameter.from(int.class, disableFlags));
+ }
+
+ private static void callDisable2MethodofStatusBarManager(int disable2Flags)
+ throws ClassNotFoundException {
+ ReflectionHelpers.callInstanceMethod(
+ Class.forName("android.app.StatusBarManager"),
+ getApplicationContext().getSystemService(Context.STATUS_BAR_SERVICE),
+ "disable2",
+ ClassParameter.from(int.class, disable2Flags));
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowStorageManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowStorageManagerTest.java
index b6392afe6..e1c4c7104 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowStorageManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowStorageManagerTest.java
@@ -6,16 +6,20 @@ import static org.robolectric.RuntimeEnvironment.application;
import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
+import android.os.Parcel;
+import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import java.io.File;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** Unit tests for {@link ShadowStorageManager}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowStorageManagerTest {
private StorageManager storageManager;
@@ -32,6 +36,24 @@ public class ShadowStorageManagerTest {
@Test
@Config(minSdk = N)
+ public void getStorageVolumes() {
+ File file1 = new File("/storage/sdcard");
+ shadowOf(storageManager).addStorageVolume(buildAndGetStorageVolume(file1, "sd card"));
+ assertThat(shadowOf(storageManager).getStorageVolumes()).isNotNull();
+ }
+
+ @Test
+ @Config(minSdk = N)
+ public void getStorageVolume() {
+ File file1 = new File("/storage/internal");
+ File file2 = new File("/storage/sdcard");
+ shadowOf(storageManager).addStorageVolume(buildAndGetStorageVolume(file1, "internal"));
+ assertThat(shadowOf(storageManager).getStorageVolume(file1)).isNotNull();
+ assertThat(shadowOf(storageManager).getStorageVolume(file2)).isNull();
+ }
+
+ @Test
+ @Config(minSdk = N)
public void isFileEncryptedNativeOrEmulated() {
shadowOf(storageManager).setFileEncryptedNativeOrEmulated(true);
assertThat(StorageManager.isFileEncryptedNativeOrEmulated()).isTrue();
@@ -43,4 +65,13 @@ public class ShadowStorageManagerTest {
shadowOf(application.getSystemService(UserManager.class)).setUserUnlocked(true);
assertThat(StorageManager.isUserKeyUnlocked(0)).isTrue();
}
+
+ private StorageVolume buildAndGetStorageVolume(File file, String description) {
+ Parcel parcel = Parcel.obtain();
+ parcel.writeInt(0);
+ UserHandle userHandle = new UserHandle(parcel);
+ StorageVolumeBuilder storageVolumeBuilder =
+ new StorageVolumeBuilder("volume", file, description, userHandle, "mounted");
+ return storageVolumeBuilder.build();
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowStrictModeTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowStrictModeTest.java
index 85b7951e0..8c047e8c5 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowStrictModeTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowStrictModeTest.java
@@ -1,11 +1,11 @@
package org.robolectric.shadows;
import android.os.StrictMode;
+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 ShadowStrictModeTest {
@Test
public void setVmPolicyTest() {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSubscriptionManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSubscriptionManagerTest.java
index df660a0b9..70f503a65 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSubscriptionManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSubscriptionManagerTest.java
@@ -6,15 +6,17 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.RuntimeEnvironment.application;
import static org.robolectric.Shadows.shadowOf;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+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.annotation.Config;
+import org.robolectric.shadows.ShadowSubscriptionManager.SubscriptionInfoBuilder;
/** Test for {@link ShadowSubscriptionManager}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = N)
public class ShadowSubscriptionManagerTest {
@@ -29,6 +31,13 @@ public class ShadowSubscriptionManagerTest {
}
@Test
+ public void shouldGiveDefaultSubscriptionId() {
+ int testId = 42;
+ ShadowSubscriptionManager.setDefaultSubscriptionId(testId);
+ assertThat(subscriptionManager.getDefaultSubscriptionId()).isEqualTo(testId);
+ }
+
+ @Test
public void shouldGiveDefaultDataSubscriptionId() {
int testId = 42;
shadowSubscriptionManager.setDefaultDataSubscriptionId(testId);
@@ -48,4 +57,120 @@ public class ShadowSubscriptionManagerTest {
shadowSubscriptionManager.setDefaultVoiceSubscriptionId(testId);
assertThat(subscriptionManager.getDefaultVoiceSubscriptionId()).isEqualTo(testId);
}
+
+ @Test
+ public void addOnSubscriptionsChangedListener_shouldAddListener() {
+ DummySubscriptionsChangedListener listener = new DummySubscriptionsChangedListener();
+ shadowSubscriptionManager.addOnSubscriptionsChangedListener(listener);
+
+ shadowSubscriptionManager.setActiveSubscriptionInfos(
+ SubscriptionInfoBuilder.newBuilder().setId(123).buildSubscriptionInfo());
+
+ assertThat(listener.subscriptionChanged).isTrue();
+ }
+
+ @Test
+ public void removeOnSubscriptionsChangedListener_shouldRemoveListener() {
+ DummySubscriptionsChangedListener listener = new DummySubscriptionsChangedListener();
+ DummySubscriptionsChangedListener listener2 = new DummySubscriptionsChangedListener();
+ shadowSubscriptionManager.addOnSubscriptionsChangedListener(listener);
+ shadowSubscriptionManager.addOnSubscriptionsChangedListener(listener2);
+
+ shadowSubscriptionManager.removeOnSubscriptionsChangedListener(listener);
+ shadowSubscriptionManager.setActiveSubscriptionInfos(
+ SubscriptionInfoBuilder.newBuilder().setId(123).buildSubscriptionInfo());
+
+ assertThat(listener.subscriptionChanged).isFalse();
+ assertThat(listener2.subscriptionChanged).isTrue();
+ }
+
+ @Test
+ public void getActiveSubscriptionInfo_shouldReturnInfoWithSubId() {
+ SubscriptionInfo expectedSubscriptionInfo =
+ SubscriptionInfoBuilder.newBuilder().setId(123).buildSubscriptionInfo();
+ shadowSubscriptionManager.setActiveSubscriptionInfos(expectedSubscriptionInfo);
+
+ assertThat(shadowSubscriptionManager.getActiveSubscriptionInfo(123))
+ .isSameAs(expectedSubscriptionInfo);
+ }
+
+ @Test
+ public void getActiveSubscriptionInfoForSimSlotIndex_shouldReturnInfoWithSlotIndex() {
+ SubscriptionInfo expectedSubscriptionInfo =
+ SubscriptionInfoBuilder.newBuilder().setSimSlotIndex(123).buildSubscriptionInfo();
+ shadowSubscriptionManager.setActiveSubscriptionInfos(expectedSubscriptionInfo);
+
+ assertThat(shadowSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(123))
+ .isSameAs(expectedSubscriptionInfo);
+ }
+
+ @Test
+ public void getActiveSubscriptionInfo_shouldReturnNullForNullList() {
+ shadowSubscriptionManager.setActiveSubscriptionInfoList(null);
+ assertThat(shadowSubscriptionManager.getActiveSubscriptionInfo(123)).isNull();
+ }
+
+ @Test
+ public void getActiveSubscriptionInfo_shouldReturnNullForNullVaargsList() {
+ shadowSubscriptionManager.setActiveSubscriptionInfos((SubscriptionInfo[]) null);
+ assertThat(shadowSubscriptionManager.getActiveSubscriptionInfo(123)).isNull();
+ }
+
+ @Test
+ public void getActiveSubscriptionInfo_shouldReturnNullForEmptyList() {
+ shadowSubscriptionManager.setActiveSubscriptionInfos();
+ assertThat(shadowSubscriptionManager.getActiveSubscriptionInfo(123)).isNull();
+ }
+
+ @Test
+ public void isNetworkRoaming_shouldReturnTrueIfSet() {
+ shadowSubscriptionManager.setNetworkRoamingStatus(123, /*isNetworkRoaming=*/ true);
+ assertThat(shadowSubscriptionManager.isNetworkRoaming(123)).isTrue();
+ }
+
+ /** Multi act-asserts are discouraged but here we are testing the set+unset. */
+ @Test
+ public void isNetworkRoaming_shouldReturnFalseIfUnset() {
+ shadowSubscriptionManager.setNetworkRoamingStatus(123, /*isNetworkRoaming=*/ true);
+ assertThat(shadowSubscriptionManager.isNetworkRoaming(123)).isTrue();
+
+ shadowSubscriptionManager.setNetworkRoamingStatus(123, /*isNetworkRoaming=*/ false);
+ assertThat(shadowSubscriptionManager.isNetworkRoaming(123)).isFalse();
+ }
+
+ /** Multi act-asserts are discouraged but here we are testing the set+clear. */
+ @Test
+ public void isNetworkRoaming_shouldReturnFalseOnClear() {
+ shadowSubscriptionManager.setNetworkRoamingStatus(123, /*isNetworkRoaming=*/ true);
+ assertThat(shadowSubscriptionManager.isNetworkRoaming(123)).isTrue();
+
+ shadowSubscriptionManager.clearNetworkRoamingStatus();
+ assertThat(shadowSubscriptionManager.isNetworkRoaming(123)).isFalse();
+ }
+
+ @Test
+ public void getActiveSubscriptionInfoCount_shouldReturnZeroIfActiveSubscriptionInfoListNotSet() {
+ shadowSubscriptionManager.setActiveSubscriptionInfoList(null);
+
+ assertThat(shadowSubscriptionManager.getActiveSubscriptionInfoCount()).isEqualTo(0);
+ }
+
+ @Test
+ public void getActiveSubscriptionInfoCount_shouldReturnSizeOfActiveSubscriotionInfosList() {
+ SubscriptionInfo expectedSubscriptionInfo =
+ SubscriptionInfoBuilder.newBuilder().setId(123).buildSubscriptionInfo();
+ shadowSubscriptionManager.setActiveSubscriptionInfos(expectedSubscriptionInfo);
+
+ assertThat(shadowSubscriptionManager.getActiveSubscriptionInfoCount()).isEqualTo(1);
+ }
+
+ private static class DummySubscriptionsChangedListener
+ extends SubscriptionManager.OnSubscriptionsChangedListener {
+ private boolean subscriptionChanged = false;
+
+ @Override
+ public void onSubscriptionsChanged() {
+ subscriptionChanged = true;
+ }
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSurfaceTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSurfaceTest.java
index f4bd4224f..5259a0705 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSurfaceTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSurfaceTest.java
@@ -5,11 +5,11 @@ import static org.robolectric.Shadows.shadowOf;
import android.graphics.SurfaceTexture;
import android.view.Surface;
+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 ShadowSurfaceTest {
private final SurfaceTexture texture = new SurfaceTexture(0);
private final Surface surface = new Surface(texture);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSurfaceViewTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSurfaceViewTest.java
index 1da99ca3b..5d1538772 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSurfaceViewTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSurfaceViewTest.java
@@ -8,12 +8,12 @@ import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowSurfaceViewTest {
private SurfaceHolder.Callback callback1 = new TestCallback();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSyncResultTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSyncResultTest.java
index cf16bdf87..a871619dc 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSyncResultTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSyncResultTest.java
@@ -5,11 +5,11 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.content.SyncResult;
+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 ShadowSyncResultTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSystemClockTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSystemClockTest.java
index 2837517f6..01a9ea9d9 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSystemClockTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSystemClockTest.java
@@ -1,5 +1,6 @@
package org.robolectric.shadows;
+import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static android.os.Build.VERSION_CODES.P;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
@@ -7,15 +8,15 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.os.SystemClock;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.time.DateTimeException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.internal.bytecode.RobolectricInternals;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowSystemClockTest {
@Test
public void shouldAllowForFakingOfTime() throws Exception {
@@ -30,7 +31,7 @@ public class ShadowSystemClockTest {
SystemClock.sleep(34);
assertThat(SystemClock.uptimeMillis()).isEqualTo(1034);
}
-
+
@Test
public void testSetCurrentTime() {
Robolectric.getForegroundThreadScheduler().advanceTo(1000);
@@ -40,7 +41,23 @@ public class ShadowSystemClockTest {
assertFalse(SystemClock.setCurrentTimeMillis(1000));
assertThat(ShadowSystemClock.now()).isEqualTo(1034);
}
-
+
+ @Test
+ public void testElapsedRealtime() {
+ Robolectric.getForegroundThreadScheduler().advanceTo(1000);
+ assertThat(SystemClock.elapsedRealtime()).isEqualTo(1000);
+ Robolectric.getForegroundThreadScheduler().advanceTo(1034);
+ assertThat(SystemClock.elapsedRealtime()).isEqualTo(1034);
+ }
+
+ @Test @Config(minSdk = JELLY_BEAN_MR1)
+ public void testElapsedRealtimeNanos() {
+ Robolectric.getForegroundThreadScheduler().advanceTo(1000);
+ assertThat(SystemClock.elapsedRealtimeNanos()).isEqualTo(1000000000);
+ Robolectric.getForegroundThreadScheduler().advanceTo(1034);
+ assertThat(SystemClock.elapsedRealtimeNanos()).isEqualTo(1034000000);
+ }
+
@Test
public void shouldInterceptSystemTimeCalls() throws Throwable {
ShadowSystemClock.setNanoTime(3141592L);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSystemPropertiesTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSystemPropertiesTest.java
index 1ea40bfbf..98f711d73 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSystemPropertiesTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSystemPropertiesTest.java
@@ -3,12 +3,12 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.os.SystemProperties;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowSystemPropertiesTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTabActivityTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTabActivityTest.java
index fcbd5071d..c7b5eb464 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTabActivityTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTabActivityTest.java
@@ -5,13 +5,13 @@ import static com.google.common.truth.Truth.assertThat;
import android.app.TabActivity;
import android.widget.TabHost;
import android.widget.TabWidget;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowTabActivityTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTabHostTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTabHostTest.java
index 1646944c3..dd83d9cc1 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTabHostTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTabHostTest.java
@@ -5,36 +5,37 @@ import static org.junit.Assert.assertNull;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
+import android.app.Application;
import android.app.TabActivity;
import android.view.View;
import android.widget.TabHost;
import android.widget.TabWidget;
import android.widget.TextView;
+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.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowTabHostTest {
@Test
public void newTabSpec_shouldMakeATabSpec() throws Exception {
- TabHost tabHost = new TabHost(RuntimeEnvironment.application);
+ TabHost tabHost = new TabHost((Application) ApplicationProvider.getApplicationContext());
TabHost.TabSpec tabSpec = tabHost.newTabSpec("Foo");
assertThat(tabSpec.getTag()).isEqualTo("Foo");
}
@Test
public void shouldAddTabsToLayoutWhenAddedToHost() {
- TabHost tabHost = new TabHost(RuntimeEnvironment.application);
+ TabHost tabHost = new TabHost((Application) ApplicationProvider.getApplicationContext());
- View fooView = new View(RuntimeEnvironment.application);
+ View fooView = new View((Application) ApplicationProvider.getApplicationContext());
TabHost.TabSpec foo = tabHost.newTabSpec("Foo").setIndicator(fooView);
- View barView = new View(RuntimeEnvironment.application);
+ View barView = new View((Application) ApplicationProvider.getApplicationContext());
TabHost.TabSpec bar = tabHost.newTabSpec("Bar").setIndicator(barView);
tabHost.addTab(foo);
@@ -46,7 +47,7 @@ public class ShadowTabHostTest {
@Test
public void shouldReturnTabSpecsByTag() throws Exception {
- TabHost tabHost = new TabHost(RuntimeEnvironment.application);
+ TabHost tabHost = new TabHost((Application) ApplicationProvider.getApplicationContext());
TabHost.TabSpec foo = tabHost.newTabSpec("Foo");
TabHost.TabSpec bar = tabHost.newTabSpec("Bar");
TabHost.TabSpec baz = tabHost.newTabSpec("Baz");
@@ -62,7 +63,7 @@ public class ShadowTabHostTest {
@Test
public void shouldFireTheTabChangeListenerWhenCurrentTabIsSet() throws Exception {
- TabHost tabHost = new TabHost(RuntimeEnvironment.application);
+ TabHost tabHost = new TabHost((Application) ApplicationProvider.getApplicationContext());
TabHost.TabSpec foo = tabHost.newTabSpec("Foo");
TabHost.TabSpec bar = tabHost.newTabSpec("Bar");
@@ -82,7 +83,7 @@ public class ShadowTabHostTest {
@Test
public void shouldFireTheTabChangeListenerWhenTheCurrentTabIsSetByTag() throws Exception {
- TabHost tabHost = new TabHost(RuntimeEnvironment.application);
+ TabHost tabHost = new TabHost((Application) ApplicationProvider.getApplicationContext());
TabHost.TabSpec foo = tabHost.newTabSpec("Foo");
TabHost.TabSpec bar = tabHost.newTabSpec("Bar");
@@ -102,14 +103,18 @@ public class ShadowTabHostTest {
@Test
public void shouldRetrieveTheCurrentViewFromTabContentFactory() {
- TabHost tabHost = new TabHost(RuntimeEnvironment.application);
-
- TabHost.TabSpec foo = tabHost.newTabSpec("Foo").setContent(
- tag -> {
- TextView tv = new TextView(RuntimeEnvironment.application);
- tv.setText("The Text of " + tag);
- return tv;
- });
+ TabHost tabHost = new TabHost((Application) ApplicationProvider.getApplicationContext());
+
+ TabHost.TabSpec foo =
+ tabHost
+ .newTabSpec("Foo")
+ .setContent(
+ tag -> {
+ TextView tv =
+ new TextView((Application) ApplicationProvider.getApplicationContext());
+ tv.setText("The Text of " + tag);
+ return tv;
+ });
tabHost.addTab(foo);
tabHost.setCurrentTabByTag("Foo");
@@ -143,7 +148,7 @@ public class ShadowTabHostTest {
@Test
public void canGetCurrentTabTag() throws Exception {
- TabHost tabHost = new TabHost(RuntimeEnvironment.application);
+ TabHost tabHost = new TabHost((Application) ApplicationProvider.getApplicationContext());
TabHost.TabSpec foo = tabHost.newTabSpec("Foo");
TabHost.TabSpec bar = tabHost.newTabSpec("Bar");
@@ -160,7 +165,7 @@ public class ShadowTabHostTest {
@Test
public void canGetCurrentTab() throws Exception {
- TabHost tabHost = new TabHost(RuntimeEnvironment.application);
+ TabHost tabHost = new TabHost((Application) ApplicationProvider.getApplicationContext());
TabHost.TabSpec foo = tabHost.newTabSpec("Foo");
TabHost.TabSpec bar = tabHost.newTabSpec("Bar");
@@ -184,7 +189,7 @@ public class ShadowTabHostTest {
@Test
public void setCurrentTabByTagShouldAcceptNullAsParameter() throws Exception {
- TabHost tabHost = new TabHost(RuntimeEnvironment.application);
+ TabHost tabHost = new TabHost((Application) ApplicationProvider.getApplicationContext());
TabHost.TabSpec foo = tabHost.newTabSpec("Foo");
tabHost.addTab(foo);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTabSpecTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTabSpecTest.java
index 7c4e8f34b..735eacaa2 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTabSpecTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTabSpecTest.java
@@ -3,6 +3,7 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
@@ -10,14 +11,14 @@ import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.TabHost;
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.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowTabSpecTest {
Drawable icon1;
@@ -28,8 +29,9 @@ public class ShadowTabSpecTest {
@Test
public void shouldGetAndSetTheIndicator() throws Exception {
- TabHost.TabSpec spec = new TabHost(RuntimeEnvironment.application).newTabSpec("foo");
- View view = new View(RuntimeEnvironment.application);
+ TabHost.TabSpec spec =
+ new TabHost((Application) ApplicationProvider.getApplicationContext()).newTabSpec("foo");
+ View view = new View((Application) ApplicationProvider.getApplicationContext());
TabHost.TabSpec self = spec.setIndicator(view);
assertThat(self).isSameAs(spec);
assertThat(shadowOf(spec).getIndicatorAsView()).isSameAs(view);
@@ -37,7 +39,8 @@ public class ShadowTabSpecTest {
@Test
public void shouldGetAndSetTheIntentContent() throws Exception {
- TabHost.TabSpec spec = new TabHost(RuntimeEnvironment.application).newTabSpec("foo");
+ TabHost.TabSpec spec =
+ new TabHost((Application) ApplicationProvider.getApplicationContext()).newTabSpec("foo");
Intent intent = new Intent();
TabHost.TabSpec self = spec.setContent(intent);
assertThat(self).isSameAs(spec);
@@ -46,8 +49,11 @@ public class ShadowTabSpecTest {
@Test
public void shouldGetAndSetTheIndicatorLabel() throws Exception {
- TabHost.TabSpec spec = new TabHost(RuntimeEnvironment.application).newTabSpec("foo")
- .setContent(R.layout.main).setIndicator("labelText");
+ TabHost.TabSpec spec =
+ new TabHost((Application) ApplicationProvider.getApplicationContext())
+ .newTabSpec("foo")
+ .setContent(R.layout.main)
+ .setIndicator("labelText");
assertThat(shadowOf(spec).getIndicatorLabel()).isEqualTo("labelText");
assertThat(shadowOf(spec).getText()).isEqualTo("labelText");
@@ -55,8 +61,11 @@ public class ShadowTabSpecTest {
@Test
public void shouldGetAndSetTheIndicatorLabelAndIcon() throws Exception {
- TabHost.TabSpec spec = new TabHost(RuntimeEnvironment.application).newTabSpec("foo")
- .setContent(R.layout.main).setIndicator("labelText", icon1);
+ TabHost.TabSpec spec =
+ new TabHost((Application) ApplicationProvider.getApplicationContext())
+ .newTabSpec("foo")
+ .setContent(R.layout.main)
+ .setIndicator("labelText", icon1);
assertThat(shadowOf(spec).getIndicatorLabel()).isEqualTo("labelText");
assertThat(shadowOf(spec).getText()).isEqualTo("labelText");
@@ -65,12 +74,16 @@ public class ShadowTabSpecTest {
@Test
public void shouldSetTheContentView() throws Exception {
- TabHost.TabSpec foo = new TabHost(RuntimeEnvironment.application).newTabSpec("Foo").setContent(
- tag -> {
- TextView tv = new TextView(RuntimeEnvironment.application);
- tv.setText("The Text of " + tag);
- return tv;
- });
+ TabHost.TabSpec foo =
+ new TabHost((Application) ApplicationProvider.getApplicationContext())
+ .newTabSpec("Foo")
+ .setContent(
+ tag -> {
+ TextView tv =
+ new TextView((Application) ApplicationProvider.getApplicationContext());
+ tv.setText("The Text of " + tag);
+ return tv;
+ });
ShadowTabHost.ShadowTabSpec shadowFoo = shadowOf(foo);
TextView textView = (TextView) shadowFoo.getContentView();
@@ -81,8 +94,10 @@ public class ShadowTabSpecTest {
@Test
public void shouldSetTheContentViewId() throws Exception {
- TabHost.TabSpec foo = new TabHost(RuntimeEnvironment.application).newTabSpec("Foo")
- .setContent(R.id.title);
+ TabHost.TabSpec foo =
+ new TabHost((Application) ApplicationProvider.getApplicationContext())
+ .newTabSpec("Foo")
+ .setContent(R.id.title);
ShadowTabHost.ShadowTabSpec shadowFoo = shadowOf(foo);
int viewId = shadowFoo.getContentViewId();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTelecomManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTelecomManagerTest.java
index cdd426068..c92509b51 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTelecomManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTelecomManagerTest.java
@@ -6,20 +6,21 @@ import static android.os.Build.VERSION_CODES.M;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowTelecomManagerTest {
@@ -27,7 +28,10 @@ public class ShadowTelecomManagerTest {
@Before
public void setUp() {
- telecomService = (TelecomManager) RuntimeEnvironment.application.getSystemService(Context.TELECOM_SERVICE);
+ telecomService =
+ (TelecomManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.TELECOM_SERVICE);
}
@Test
@@ -151,6 +155,57 @@ public class ShadowTelecomManagerTest {
}
@Test
+ public void testIsRinging_noIncomingOrUnknownCallsAdded_shouldBeFalse() {
+ assertThat(shadowOf(telecomService).isRinging()).isFalse();
+ }
+
+ @Test
+ public void testIsRinging_incomingCallAdded_shouldBeTrue() {
+ telecomService.addNewIncomingCall(createHandle("id"), null);
+
+ assertThat(shadowOf(telecomService).isRinging()).isTrue();
+ }
+
+ @Test
+ public void testIsRinging_unknownCallAdded_shouldBeTrue() {
+ shadowOf(telecomService).addNewUnknownCall(createHandle("id"), null);
+
+ assertThat(shadowOf(telecomService).isRinging()).isTrue();
+ }
+
+ @Test
+ public void testIsRinging_incomingCallAdded_thenRingerSilenced_shouldBeFalse() {
+ telecomService.addNewIncomingCall(createHandle("id"), null);
+ telecomService.silenceRinger();
+
+ assertThat(shadowOf(telecomService).isRinging()).isFalse();
+ }
+
+ @Test
+ public void testIsRinging_unknownCallAdded_thenRingerSilenced_shouldBeFalse() {
+ shadowOf(telecomService).addNewUnknownCall(createHandle("id"), null);
+ telecomService.silenceRinger();
+
+ assertThat(shadowOf(telecomService).isRinging()).isFalse();
+ }
+
+ @Test
+ public void testIsRinging_ringerSilenced_thenIncomingCallAdded_shouldBeTrue() {
+ telecomService.silenceRinger();
+ telecomService.addNewIncomingCall(createHandle("id"), null);
+
+ assertThat(shadowOf(telecomService).isRinging()).isTrue();
+ }
+
+ @Test
+ public void testIsRinging_ringerSilenced_thenUnknownCallAdded_shouldBeTrue() {
+ telecomService.silenceRinger();
+ shadowOf(telecomService).addNewUnknownCall(createHandle("id"), null);
+
+ assertThat(shadowOf(telecomService).isRinging()).isTrue();
+ }
+
+ @Test
@Config(minSdk = M)
public void setDefaultDialerPackage() {
shadowOf(telecomService).setDefaultDialer("some.package");
@@ -158,7 +213,8 @@ public class ShadowTelecomManagerTest {
}
private static PhoneAccountHandle createHandle(String id) {
- return createHandle(RuntimeEnvironment.application.getPackageName(), id);
+ return createHandle(
+ ((Application) ApplicationProvider.getApplicationContext()).getPackageName(), id);
}
private static PhoneAccountHandle createHandle(String packageName, String id) {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyManagerTest.java
index 937f04b28..b1123a8e7 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyManagerTest.java
@@ -22,6 +22,7 @@ import static org.mockito.Mockito.verify;
import static org.robolectric.RuntimeEnvironment.application;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
@@ -34,16 +35,16 @@ import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowTelephonyManagerTest {
private TelephonyManager telephonyManager;
@@ -112,6 +113,19 @@ public class ShadowTelephonyManagerTest {
assertEquals("SomeSimOperatorName", telephonyManager.getSimOperatorName());
}
+ @Test(expected = SecurityException.class)
+ public void getSimSerialNumber_shouldThrowSecurityExceptionWhenReadPhoneStatePermissionNotGranted()
+ throws Exception {
+ shadowTelephonyManager.setReadPhoneStatePermission(false);
+ telephonyManager.getSimSerialNumber();
+ }
+
+ @Test
+ public void shouldGetSimSerialNumber() {
+ shadowTelephonyManager.setSimSerialNumber("SomeSerialNumber");
+ assertEquals("SomeSerialNumber", telephonyManager.getSimSerialNumber());
+ }
+
@Test
public void shouldGiveNetworkType() {
shadowTelephonyManager.setNetworkType(TelephonyManager.NETWORK_TYPE_CDMA);
@@ -119,6 +133,14 @@ public class ShadowTelephonyManagerTest {
}
@Test
+ @Config(minSdk = N)
+ public void shouldGiveVoiceNetworkType() {
+ shadowTelephonyManager.setVoiceNetworkType(TelephonyManager.NETWORK_TYPE_CDMA);
+ assertThat(telephonyManager.getVoiceNetworkType())
+ .isEqualTo(TelephonyManager.NETWORK_TYPE_CDMA);
+ }
+
+ @Test
@Config(minSdk = JELLY_BEAN_MR1)
public void shouldGiveAllCellInfo() {
PhoneStateListener listener = mock(PhoneStateListener.class);
@@ -245,7 +267,9 @@ public class ShadowTelephonyManagerTest {
public void shouldGiveVoiceVibrationEnabled() {
PhoneAccountHandle phoneAccountHandle =
new PhoneAccountHandle(
- new ComponentName(RuntimeEnvironment.application, Object.class), "handle");
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(), Object.class),
+ "handle");
shadowTelephonyManager.setVoicemailVibrationEnabled(phoneAccountHandle, true);
@@ -257,7 +281,9 @@ public class ShadowTelephonyManagerTest {
public void shouldGiveVoicemailRingtoneUri() {
PhoneAccountHandle phoneAccountHandle =
new PhoneAccountHandle(
- new ComponentName(RuntimeEnvironment.application, Object.class), "handle");
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(), Object.class),
+ "handle");
Uri ringtoneUri = Uri.fromParts("file", "ringtone.mp3", /* fragment = */ null);
shadowTelephonyManager.setVoicemailRingtoneUri(phoneAccountHandle, ringtoneUri);
@@ -270,7 +296,9 @@ public class ShadowTelephonyManagerTest {
public void shouldSetVoicemailRingtoneUri() {
PhoneAccountHandle phoneAccountHandle =
new PhoneAccountHandle(
- new ComponentName(RuntimeEnvironment.application, Object.class), "handle");
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(), Object.class),
+ "handle");
Uri ringtoneUri = Uri.fromParts("file", "ringtone.mp3", /* fragment = */ null);
// Note: Using the real manager to set, instead of the shadow.
@@ -284,7 +312,9 @@ public class ShadowTelephonyManagerTest {
public void shouldCreateForPhoneAccountHandle() {
PhoneAccountHandle phoneAccountHandle =
new PhoneAccountHandle(
- new ComponentName(RuntimeEnvironment.application, Object.class), "handle");
+ new ComponentName(
+ (Application) ApplicationProvider.getApplicationContext(), Object.class),
+ "handle");
TelephonyManager mockTelephonyManager = mock(TelephonyManager.class);
shadowTelephonyManager.setTelephonyManagerForHandle(phoneAccountHandle, mockTelephonyManager);
@@ -407,4 +437,12 @@ public class ShadowTelephonyManagerTest {
assertThat(shadowTelephonyManager.getSimCountryIso()).isEmpty();
}
+
+ @Test
+ public void shouldSetSubscriberId() {
+ String subscriberId = "123451234512345";
+ shadowTelephonyManager.setSubscriberId(subscriberId);
+
+ assertThat(shadowTelephonyManager.getSubscriberId()).isEqualTo(subscriberId);
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyTest.java
new file mode 100644
index 000000000..18dc58797
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyTest.java
@@ -0,0 +1,45 @@
+package org.robolectric.shadows;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Application;
+import android.content.Context;
+import android.os.Build.VERSION_CODES;
+import android.provider.Telephony.Sms;
+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.annotation.Config;
+import org.robolectric.shadows.ShadowTelephony.ShadowSms;
+
+/** Unit tests for {@link ShadowTelephony}. */
+@RunWith(AndroidJUnit4.class)
+@Config(minSdk = VERSION_CODES.KITKAT)
+public class ShadowTelephonyTest {
+ private static final String TEST_PACKAGE_NAME = "test.package.name";
+
+ private Context context;
+
+ @Before
+ public void setUp() {
+ context = (Application) ApplicationProvider.getApplicationContext();
+ }
+
+ @Test
+ public void shadowSms_getDefaultSmsPackage() {
+ ShadowSms.setDefaultSmsPackage(TEST_PACKAGE_NAME);
+
+ assertThat(Sms.getDefaultSmsPackage(context)).isEqualTo(TEST_PACKAGE_NAME);
+ }
+
+ @Test
+ public void shadowSms_getDefaultSmsPackage_returnsNull_whenNoSmsPackageIsSet() {
+ // Make sure #reset is doing its job
+ ShadowSms.setDefaultSmsPackage(TEST_PACKAGE_NAME);
+ ShadowSms.reset();
+
+ assertThat(Sms.getDefaultSmsPackage(context)).isNull();
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTest.java
index 66308c319..8646217af 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTest.java
@@ -4,13 +4,13 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
+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.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowTest {
private ClassLoader myClassLoader;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTextPaintTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTextPaintTest.java
index 9fe12e1d2..f60493691 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTextPaintTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTextPaintTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.text.TextPaint;
+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 ShadowTextPaintTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTextToSpeechTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTextToSpeechTest.java
index 7929a229c..042057f11 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTextToSpeechTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTextToSpeechTest.java
@@ -5,13 +5,13 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
import android.speech.tts.TextToSpeech;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowTextToSpeechTest {
private TextToSpeech textToSpeech;
private Activity activity;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTextUtilsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTextUtilsTest.java
index a548f776d..23f6dffad 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTextUtilsTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTextUtilsTest.java
@@ -5,12 +5,12 @@ import static org.junit.Assert.assertArrayEquals;
import android.text.TextPaint;
import android.text.TextUtils;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowTextUtilsTest {
@Test
public void testExpandTemplate() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTextViewTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTextViewTest.java
index d0ee2d4db..e849b0238 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTextViewTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTextViewTest.java
@@ -15,6 +15,7 @@ import static org.robolectric.Robolectric.buildActivity;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
+import android.app.Application;
import android.graphics.Typeface;
import android.text.Editable;
import android.text.InputFilter;
@@ -35,6 +36,8 @@ import android.view.MotionEvent;
import android.view.inputmethod.EditorInfo;
import android.widget.FrameLayout;
import android.widget.TextView;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@@ -44,12 +47,10 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.shadow.api.Shadow;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowTextViewTest {
private static final String INITIAL_TEXT = "initial text";
@@ -93,8 +94,8 @@ public class ShadowTextViewTest {
textView.setText("here's some text http://google.com/\nblah\thttp://another.com/123?456 blah");
assertThat(urlStringsFrom(textView.getUrls())).isEqualTo(asList(
- "http://google.com",
- "http://another.com/123?456"
+ "http://google.com",
+ "http://another.com/123?456"
));
}
@@ -127,7 +128,9 @@ public class ShadowTextViewTest {
@Test
public void testGetTextAppearanceId() throws Exception {
- textView.setTextAppearance(RuntimeEnvironment.application, android.R.style.TextAppearance_Small);
+ textView.setTextAppearance(
+ (Application) ApplicationProvider.getApplicationContext(),
+ android.R.style.TextAppearance_Small);
assertThat(shadowOf(textView).getTextAppearanceId()).isEqualTo(android.R.style.TextAppearance_Small);
}
@@ -439,7 +442,11 @@ public class ShadowTextViewTest {
@Test
public void setTextSize_shouldHandleDips() throws Exception {
- RuntimeEnvironment.application.getResources().getDisplayMetrics().density = 1.5f;
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getDisplayMetrics()
+ .density =
+ 1.5f;
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10);
assertThat(textView.getTextSize()).isEqualTo(15f);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
@@ -451,7 +458,11 @@ public class ShadowTextViewTest {
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
assertThat(textView.getTextSize()).isEqualTo(10f);
- RuntimeEnvironment.application.getResources().getDisplayMetrics().scaledDensity = 1.5f;
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getDisplayMetrics()
+ .scaledDensity =
+ 1.5f;
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
assertThat(textView.getTextSize()).isEqualTo(15f);
@@ -459,7 +470,11 @@ public class ShadowTextViewTest {
@Test
public void setTextSize_shouldHandlePixels() throws Exception {
- RuntimeEnvironment.application.getResources().getDisplayMetrics().density = 1.5f;
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getDisplayMetrics()
+ .density =
+ 1.5f;
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 10);
assertThat(textView.getTextSize()).isEqualTo(10f);
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 20);
@@ -588,7 +603,7 @@ public class ShadowTextViewTest {
@Override
public boolean onGenericMotionEvent(TextView widget, Spannable text,
- MotionEvent event) {
+ MotionEvent event) {
return false;
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowThemeTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowThemeTest.java
index 7bc8f31b1..b97c61213 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowThemeTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowThemeTest.java
@@ -4,6 +4,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Robolectric.buildActivity;
import android.app.Activity;
+import android.app.Application;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
@@ -14,24 +15,24 @@ import android.util.AttributeSet;
import android.util.Xml;
import android.view.View;
import android.widget.Button;
+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.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.controller.ActivityController;
import org.xmlpull.v1.XmlPullParser;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowThemeTest {
private Resources resources;
@Before
public void setUp() throws Exception {
- resources = RuntimeEnvironment.application.getResources();
+ resources = ((Application) ApplicationProvider.getApplicationContext()).getResources();
}
@After
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTileServiceTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTileServiceTest.java
index 860c80e8a..671be4265 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTileServiceTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTileServiceTest.java
@@ -5,14 +5,14 @@ import static com.google.common.truth.Truth.assertThat;
import android.os.Build;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
+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.annotation.Config;
/** Test for {@link org.robolectric.shadows.ShadowTileService}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(sdk = Build.VERSION_CODES.N)
public final class ShadowTileServiceTest {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTileTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTileTest.java
index 19b1bf53f..3c6d7ed56 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTileTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTileTest.java
@@ -4,15 +4,15 @@ import static org.robolectric.Shadows.shadowOf;
import android.os.Build;
import android.service.quicksettings.Tile;
+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.annotation.Config;
import org.robolectric.shadow.api.Shadow;
/** test for {@link org.robolectric.shadows.ShadowTile}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(sdk = Build.VERSION_CODES.N)
public final class ShadowTileTest {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTimePickerDialogTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTimePickerDialogTest.java
index 04cc2704b..cdb64c82e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTimePickerDialogTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTimePickerDialogTest.java
@@ -3,18 +3,21 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.TimePickerDialog;
+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 ShadowTimePickerDialogTest {
@Test
public void returnsTheIntialHourAndMinutePassedIntoTheTimePickerDialog() throws Exception {
- TimePickerDialog timePickerDialog = new TimePickerDialog(RuntimeEnvironment.application, 0, null, 6, 55, false);
+ TimePickerDialog timePickerDialog =
+ new TimePickerDialog(
+ (Application) ApplicationProvider.getApplicationContext(), 0, null, 6, 55, false);
ShadowTimePickerDialog shadow = shadowOf(timePickerDialog);
assertThat(shadow.getHourOfDay()).isEqualTo(6);
assertThat(shadow.getMinute()).isEqualTo(55);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTimeTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTimeTest.java
index 9b5466354..faaa7fc1c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTimeTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTimeTest.java
@@ -11,15 +11,15 @@ import static org.junit.Assert.assertTrue;
import android.os.SystemClock;
import android.text.format.Time;
import android.util.TimeFormatException;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Arrays;
import java.util.TimeZone;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = JELLY_BEAN_MR2)
public class ShadowTimeTest {
private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getDefault();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTimeZoneFinderTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTimeZoneFinderTest.java
index 970fe080b..45a6df31c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTimeZoneFinderTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTimeZoneFinderTest.java
@@ -4,15 +4,15 @@ import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
import android.icu.util.TimeZone;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.stream.Collectors;
import libcore.util.TimeZoneFinder;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** Unit tests for {@link ShadowTimeZoneFinder}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowTimeZoneFinderTest {
@Test
@@ -20,11 +20,11 @@ public class ShadowTimeZoneFinderTest {
public void test() {
TimeZoneFinder timeZoneFinder = TimeZoneFinder.getInstance();
assertThat(
- timeZoneFinder
- .lookupTimeZonesByCountry("us")
- .stream()
- .map(TimeZone::getID)
- .collect(Collectors.toList()))
+ timeZoneFinder
+ .lookupTimeZonesByCountry("us")
+ .stream()
+ .map(TimeZone::getID)
+ .collect(Collectors.toList()))
.containsAllOf("America/Los_Angeles", "America/New_York", "Pacific/Honolulu");
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowToastTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowToastTest.java
index 18799a594..6a1614b08 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowToastTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowToastTest.java
@@ -3,35 +3,48 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.view.Gravity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
+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.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowToastTest {
@Test
public void shouldHaveShortDuration() throws Exception {
- Toast toast = Toast.makeText(RuntimeEnvironment.application, "short toast", Toast.LENGTH_SHORT);
+ Toast toast =
+ Toast.makeText(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "short toast",
+ Toast.LENGTH_SHORT);
assertThat(toast).isNotNull();
assertThat(toast.getDuration()).isEqualTo(Toast.LENGTH_SHORT);
}
@Test
public void shouldHaveLongDuration() throws Exception {
- Toast toast = Toast.makeText(RuntimeEnvironment.application, "long toast", Toast.LENGTH_LONG);
+ Toast toast =
+ Toast.makeText(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "long toast",
+ Toast.LENGTH_LONG);
assertThat(toast).isNotNull();
assertThat(toast.getDuration()).isEqualTo(Toast.LENGTH_LONG);
}
@Test
public void shouldMakeTextCorrectly() throws Exception {
- Toast toast = Toast.makeText(RuntimeEnvironment.application, "short toast", Toast.LENGTH_SHORT);
+ Toast toast =
+ Toast.makeText(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "short toast",
+ Toast.LENGTH_SHORT);
assertThat(toast).isNotNull();
assertThat(toast.getDuration()).isEqualTo(Toast.LENGTH_SHORT);
toast.show();
@@ -42,7 +55,11 @@ public class ShadowToastTest {
@Test
public void shouldSetTextCorrectly() throws Exception {
- Toast toast = Toast.makeText(RuntimeEnvironment.application, "short toast", Toast.LENGTH_SHORT);
+ Toast toast =
+ Toast.makeText(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "short toast",
+ Toast.LENGTH_SHORT);
toast.setText("other toast");
toast.show();
assertThat(ShadowToast.getLatestToast()).isSameAs(toast);
@@ -52,7 +69,11 @@ public class ShadowToastTest {
@Test
public void shouldSetTextWithIdCorrectly() throws Exception {
- Toast toast = Toast.makeText(RuntimeEnvironment.application, "short toast", Toast.LENGTH_SHORT);
+ Toast toast =
+ Toast.makeText(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "short toast",
+ Toast.LENGTH_SHORT);
toast.setText(R.string.hello);
toast.show();
assertThat(ShadowToast.getLatestToast()).isSameAs(toast);
@@ -62,16 +83,20 @@ public class ShadowToastTest {
@Test
public void shouldSetViewCorrectly() throws Exception {
- Toast toast = new Toast(RuntimeEnvironment.application);
+ Toast toast = new Toast((Application) ApplicationProvider.getApplicationContext());
toast.setDuration(Toast.LENGTH_SHORT);
- final View view = new TextView(RuntimeEnvironment.application);
+ final View view = new TextView((Application) ApplicationProvider.getApplicationContext());
toast.setView(view);
assertThat(toast.getView()).isSameAs(view);
}
@Test
public void shouldSetGravityCorrectly() throws Exception {
- Toast toast = Toast.makeText(RuntimeEnvironment.application, "short toast", Toast.LENGTH_SHORT);
+ Toast toast =
+ Toast.makeText(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "short toast",
+ Toast.LENGTH_SHORT);
assertThat(toast).isNotNull();
toast.setGravity(Gravity.CENTER, 0, 0);
assertThat(toast.getGravity()).isEqualTo(Gravity.CENTER);
@@ -79,7 +104,11 @@ public class ShadowToastTest {
@Test
public void shouldSetOffsetsCorrectly() throws Exception {
- Toast toast = Toast.makeText(RuntimeEnvironment.application, "short toast", Toast.LENGTH_SHORT);
+ Toast toast =
+ Toast.makeText(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "short toast",
+ Toast.LENGTH_SHORT);
toast.setGravity(0, 12, 34);
assertThat(toast.getXOffset()).isEqualTo(12);
assertThat(toast.getYOffset()).isEqualTo(34);
@@ -88,7 +117,11 @@ public class ShadowToastTest {
@Test
public void shouldCountToastsCorrectly() throws Exception {
assertThat(ShadowToast.shownToastCount()).isEqualTo(0);
- Toast toast = Toast.makeText(RuntimeEnvironment.application, "short toast", Toast.LENGTH_SHORT);
+ Toast toast =
+ Toast.makeText(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "short toast",
+ Toast.LENGTH_SHORT);
assertThat(toast).isNotNull();
toast.show();
toast.show();
@@ -103,7 +136,11 @@ public class ShadowToastTest {
@Test
public void shouldBeCancelled() throws Exception {
- Toast toast = Toast.makeText(RuntimeEnvironment.application, "short toast", Toast.LENGTH_SHORT);
+ Toast toast =
+ Toast.makeText(
+ (Application) ApplicationProvider.getApplicationContext(),
+ "short toast",
+ Toast.LENGTH_SHORT);
toast.cancel();
ShadowToast shadowToast = shadowOf(toast);
assertThat(shadowToast.isCancelled()).isTrue();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTouchDelegateTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTouchDelegateTest.java
index 7bb2fd51d..29ee5f05f 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTouchDelegateTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTouchDelegateTest.java
@@ -2,17 +2,18 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.graphics.Rect;
import android.view.TouchDelegate;
import android.view.View;
+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;
import org.robolectric.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowTouchDelegateTest {
private ShadowTouchDelegate td;
@@ -22,7 +23,7 @@ public class ShadowTouchDelegateTest {
@Before
public void setUp() throws Exception {
rect = new Rect(1, 2, 3, 4);
- view = new View(RuntimeEnvironment.application);
+ view = new View((Application) ApplicationProvider.getApplicationContext());
TouchDelegate realTD = new TouchDelegate(rect, view);
td = Shadows.shadowOf(realTD);
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTrafficStatsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTrafficStatsTest.java
index 7ed2d57a1..54448edfa 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTrafficStatsTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTrafficStatsTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
import static org.junit.Assert.assertEquals;
import android.net.TrafficStats;
+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 ShadowTrafficStatsTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTypedArrayTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTypedArrayTest.java
index edee39d62..853f4811a 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTypedArrayTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTypedArrayTest.java
@@ -3,25 +3,26 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNotNull;
+import android.app.Application;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.ColorDrawable;
+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.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.res.AttributeResource;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowTypedArrayTest {
private Context context;
@Before
public void setUp() throws Exception {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTypefaceTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTypefaceTest.java
index cc4042792..8346b5e92 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTypefaceTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTypefaceTest.java
@@ -4,17 +4,18 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.graphics.Typeface;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.File;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.res.FileFsFile;
import org.robolectric.util.TestUtil;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowTypefaceTest {
private File fontFile;
@@ -70,7 +71,8 @@ public class ShadowTypefaceTest {
@Test
public void createFromAsset_shouldCreateTypeface() {
Typeface typeface =
- Typeface.createFromAsset(RuntimeEnvironment.application.getAssets(), "myFont.ttf");
+ Typeface.createFromAsset(
+ ((Application) ApplicationProvider.getApplicationContext()).getAssets(), "myFont.ttf");
assertThat(typeface.getStyle()).isEqualTo(Typeface.NORMAL);
assertThat(shadowOf(typeface).getFontDescription().getFamilyName()).isEqualTo("myFont.ttf");
@@ -80,7 +82,9 @@ public class ShadowTypefaceTest {
@Test
public void createFromAsset_throwsExceptionWhenFontNotFound() throws Exception {
try {
- Typeface.createFromAsset(RuntimeEnvironment.application.getAssets(), "nonexistent.ttf");
+ Typeface.createFromAsset(
+ ((Application) ApplicationProvider.getApplicationContext()).getAssets(),
+ "nonexistent.ttf");
fail("Expected exception");
} catch (RuntimeException expected) {
// Expected
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowUriTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowUriTest.java
index 3d074b386..92bc236ba 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowUriTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowUriTest.java
@@ -3,11 +3,11 @@ package org.robolectric.shadows;
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 ShadowUriTest {
@Test
public void shouldParseUris() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowUsageStatsManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowUsageStatsManagerTest.java
index fe921fa98..31b9c0909 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowUsageStatsManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowUsageStatsManagerTest.java
@@ -8,6 +8,7 @@ import static com.google.common.truth.Truth.assertThat;
import static java.util.concurrent.TimeUnit.HOURS;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.app.PendingIntent;
import android.app.usage.UsageEvents;
import android.app.usage.UsageEvents.Event;
@@ -15,6 +16,8 @@ import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Intent;
import android.os.Build;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import java.util.Collections;
import java.util.List;
@@ -23,14 +26,12 @@ import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowUsageStatsManager.AppUsageObserver;
import org.robolectric.shadows.ShadowUsageStatsManager.UsageStatsBuilder;
/** Test for {@link ShadowUsageStatsManager}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = LOLLIPOP)
public class ShadowUsageStatsManagerTest {
@@ -43,7 +44,9 @@ public class ShadowUsageStatsManagerTest {
@Before
public void setUp() throws Exception {
usageStatsManager =
- (UsageStatsManager) RuntimeEnvironment.application.getSystemService(USAGE_STATS_SERVICE);
+ (UsageStatsManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(USAGE_STATS_SERVICE);
}
@Test
@@ -98,6 +101,50 @@ public class ShadowUsageStatsManagerTest {
}
@Test
+ public void testQueryEvents_appendEventData_simulateTimeChange_shouldAddOffsetToPreviousData()
+ throws Exception {
+ shadowOf(usageStatsManager).addEvent(TEST_PACKAGE_NAME1, 500L, Event.MOVE_TO_FOREGROUND);
+ shadowOf(usageStatsManager).addEvent(TEST_PACKAGE_NAME1, 1000L, Event.MOVE_TO_BACKGROUND);
+ shadowOf(usageStatsManager)
+ .addEvent(
+ ShadowUsageStatsManager.EventBuilder.buildEvent()
+ .setTimeStamp(1500L)
+ .setPackage(TEST_PACKAGE_NAME2)
+ .setClass(TEST_ACTIVITY_NAME)
+ .setEventType(Event.MOVE_TO_FOREGROUND)
+ .build());
+ shadowOf(usageStatsManager).addEvent(TEST_PACKAGE_NAME2, 2000L, Event.MOVE_TO_BACKGROUND);
+ shadowOf(usageStatsManager)
+ .addEvent(
+ ShadowUsageStatsManager.EventBuilder.buildEvent()
+ .setTimeStamp(2500L)
+ .setPackage(TEST_PACKAGE_NAME1)
+ .setEventType(Event.MOVE_TO_FOREGROUND)
+ .setClass(TEST_ACTIVITY_NAME)
+ .build());
+ shadowOf(usageStatsManager).simulateTimeChange(10000L);
+
+ UsageEvents events = usageStatsManager.queryEvents(11000L, 12000L);
+ Event event = new Event();
+
+ assertThat(events.hasNextEvent()).isTrue();
+ assertThat(events.getNextEvent(event)).isTrue();
+ assertThat(event.getPackageName()).isEqualTo(TEST_PACKAGE_NAME1);
+ assertThat(event.getTimeStamp()).isEqualTo(11000L);
+ assertThat(event.getEventType()).isEqualTo(Event.MOVE_TO_BACKGROUND);
+
+ assertThat(events.hasNextEvent()).isTrue();
+ assertThat(events.getNextEvent(event)).isTrue();
+ assertThat(event.getPackageName()).isEqualTo(TEST_PACKAGE_NAME2);
+ assertThat(event.getTimeStamp()).isEqualTo(11500L);
+ assertThat(event.getEventType()).isEqualTo(Event.MOVE_TO_FOREGROUND);
+ assertThat(event.getClassName()).isEqualTo(TEST_ACTIVITY_NAME);
+
+ assertThat(events.hasNextEvent()).isFalse();
+ assertThat(events.getNextEvent(event)).isFalse();
+ }
+
+ @Test
@Config(minSdk = Build.VERSION_CODES.P)
public void testGetAppStandbyBucket_withPackageName() throws Exception {
assertThat(shadowOf(usageStatsManager).getAppStandbyBuckets()).isEmpty();
@@ -144,11 +191,13 @@ public class ShadowUsageStatsManagerTest {
@Config(minSdk = Build.VERSION_CODES.P)
public void testRegisterAppUsageObserver_uniqueObserverIds_shouldAddBothObservers() {
PendingIntent pendingIntent1 =
- PendingIntent.getBroadcast(RuntimeEnvironment.application, 0, new Intent("ACTION1"), 0);
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(), 0, new Intent("ACTION1"), 0);
usageStatsManager.registerAppUsageObserver(
12, new String[] {"com.package1", "com.package2"}, 123L, TimeUnit.MINUTES, pendingIntent1);
PendingIntent pendingIntent2 =
- PendingIntent.getBroadcast(RuntimeEnvironment.application, 0, new Intent("ACTION2"), 0);
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(), 0, new Intent("ACTION2"), 0);
usageStatsManager.registerAppUsageObserver(
24, new String[] {"com.package3"}, 456L, TimeUnit.SECONDS, pendingIntent2);
@@ -168,11 +217,13 @@ public class ShadowUsageStatsManagerTest {
@Config(minSdk = Build.VERSION_CODES.P)
public void testRegisterAppUsageObserver_duplicateObserverIds_shouldOverrideExistingObserver() {
PendingIntent pendingIntent1 =
- PendingIntent.getBroadcast(RuntimeEnvironment.application, 0, new Intent("ACTION1"), 0);
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(), 0, new Intent("ACTION1"), 0);
usageStatsManager.registerAppUsageObserver(
12, new String[] {"com.package1", "com.package2"}, 123L, TimeUnit.MINUTES, pendingIntent1);
PendingIntent pendingIntent2 =
- PendingIntent.getBroadcast(RuntimeEnvironment.application, 0, new Intent("ACTION2"), 0);
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(), 0, new Intent("ACTION2"), 0);
usageStatsManager.registerAppUsageObserver(
12, new String[] {"com.package3"}, 456L, TimeUnit.SECONDS, pendingIntent2);
@@ -186,11 +237,13 @@ public class ShadowUsageStatsManagerTest {
@Config(minSdk = Build.VERSION_CODES.P)
public void testUnregisterAppUsageObserver_existingObserverId_shouldRemoveObserver() {
PendingIntent pendingIntent1 =
- PendingIntent.getBroadcast(RuntimeEnvironment.application, 0, new Intent("ACTION1"), 0);
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(), 0, new Intent("ACTION1"), 0);
usageStatsManager.registerAppUsageObserver(
12, new String[] {"com.package1", "com.package2"}, 123L, TimeUnit.MINUTES, pendingIntent1);
PendingIntent pendingIntent2 =
- PendingIntent.getBroadcast(RuntimeEnvironment.application, 0, new Intent("ACTION2"), 0);
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(), 0, new Intent("ACTION2"), 0);
usageStatsManager.registerAppUsageObserver(
24, new String[] {"com.package3"}, 456L, TimeUnit.SECONDS, pendingIntent2);
@@ -206,11 +259,13 @@ public class ShadowUsageStatsManagerTest {
@Config(minSdk = Build.VERSION_CODES.P)
public void testUnregisterAppUsageObserver_nonExistentObserverId_shouldBeNoOp() {
PendingIntent pendingIntent1 =
- PendingIntent.getBroadcast(RuntimeEnvironment.application, 0, new Intent("ACTION1"), 0);
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(), 0, new Intent("ACTION1"), 0);
usageStatsManager.registerAppUsageObserver(
12, new String[] {"com.package1", "com.package2"}, 123L, TimeUnit.MINUTES, pendingIntent1);
PendingIntent pendingIntent2 =
- PendingIntent.getBroadcast(RuntimeEnvironment.application, 0, new Intent("ACTION2"), 0);
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(), 0, new Intent("ACTION2"), 0);
usageStatsManager.registerAppUsageObserver(
24, new String[] {"com.package3"}, 456L, TimeUnit.SECONDS, pendingIntent2);
@@ -232,17 +287,20 @@ public class ShadowUsageStatsManagerTest {
@Config(minSdk = Build.VERSION_CODES.P)
public void testTriggerRegisteredAppUsageObserver_shouldSendIntentAndRemoveObserver() {
PendingIntent pendingIntent1 =
- PendingIntent.getBroadcast(RuntimeEnvironment.application, 0, new Intent("ACTION1"), 0);
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(), 0, new Intent("ACTION1"), 0);
usageStatsManager.registerAppUsageObserver(
12, new String[] {"com.package1", "com.package2"}, 123L, TimeUnit.MINUTES, pendingIntent1);
PendingIntent pendingIntent2 =
- PendingIntent.getBroadcast(RuntimeEnvironment.application, 0, new Intent("ACTION2"), 0);
+ PendingIntent.getBroadcast(
+ (Application) ApplicationProvider.getApplicationContext(), 0, new Intent("ACTION2"), 0);
usageStatsManager.registerAppUsageObserver(
24, new String[] {"com.package3"}, 456L, TimeUnit.SECONDS, pendingIntent2);
shadowOf(usageStatsManager).triggerRegisteredAppUsageObserver(24, 500000L);
- List<Intent> broadcastIntents = shadowOf(RuntimeEnvironment.application).getBroadcastIntents();
+ List<Intent> broadcastIntents =
+ shadowOf((Application) ApplicationProvider.getApplicationContext()).getBroadcastIntents();
assertThat(broadcastIntents).hasSize(1);
Intent broadcastIntent = broadcastIntents.get(0);
assertThat(broadcastIntent.getAction()).isEqualTo("ACTION2");
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowUsbManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowUsbManagerTest.java
index 5931ddef4..7a0af700f 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowUsbManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowUsbManagerTest.java
@@ -7,12 +7,15 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbPort;
import android.hardware.usb.UsbPortStatus;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.junit.Before;
@@ -20,12 +23,10 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/** Unit tests for {@link ShadowUsbManager}. */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowUsbManagerTest {
private static final String DEVICE_NAME_1 = "usb1";
private static final String DEVICE_NAME_2 = "usb2";
@@ -39,7 +40,10 @@ public class ShadowUsbManagerTest {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- usbManager = (UsbManager) RuntimeEnvironment.application.getSystemService(Context.USB_SERVICE);
+ usbManager =
+ (UsbManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.USB_SERVICE);
shadowUsbManager = shadowOf(usbManager);
when(usbDevice1.getDeviceName()).thenReturn(DEVICE_NAME_1);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowUserManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowUserManagerTest.java
index 2cdca2ff5..a16c5b502 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowUserManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowUserManagerTest.java
@@ -1,5 +1,22 @@
package org.robolectric.shadows;
+import static android.content.pm.PackageManager.GET_ACTIVITIES;
+import static android.content.pm.PackageManager.GET_CONFIGURATIONS;
+import static android.content.pm.PackageManager.GET_DISABLED_COMPONENTS;
+import static android.content.pm.PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS;
+import static android.content.pm.PackageManager.GET_GIDS;
+import static android.content.pm.PackageManager.GET_INSTRUMENTATION;
+import static android.content.pm.PackageManager.GET_INTENT_FILTERS;
+import static android.content.pm.PackageManager.GET_META_DATA;
+import static android.content.pm.PackageManager.GET_PERMISSIONS;
+import static android.content.pm.PackageManager.GET_PROVIDERS;
+import static android.content.pm.PackageManager.GET_RECEIVERS;
+import static android.content.pm.PackageManager.GET_SERVICES;
+import static android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES;
+import static android.content.pm.PackageManager.GET_SIGNATURES;
+import static android.content.pm.PackageManager.GET_SIGNING_CERTIFICATES;
+import static android.content.pm.PackageManager.GET_UNINSTALLED_PACKAGES;
+import static android.content.pm.PackageManager.GET_URI_PERMISSION_PATTERNS;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
import static android.os.Build.VERSION_CODES.KITKAT_WATCH;
@@ -12,23 +29,23 @@ import static org.junit.Assert.fail;
import static org.robolectric.Shadows.shadowOf;
import android.Manifest.permission;
+import android.app.Application;
import android.content.Context;
import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
+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;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowUserManager.UserState;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowUserManagerTest {
private UserManager userManager;
@@ -36,7 +53,7 @@ public class ShadowUserManagerTest {
@Before
public void setUp() {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
}
@@ -61,7 +78,11 @@ public class ShadowUserManagerTest {
restrictions.putCharSequence("test_key", "test_value");
shadowOf(userManager).setApplicationRestrictions(packageName, restrictions);
- assertThat(userManager.getApplicationRestrictions(packageName).getCharSequence("test_key"))
+ assertThat(
+ userManager
+ .getApplicationRestrictions(packageName)
+ .getCharSequence("test_key")
+ .toString())
.isEqualTo("test_value");
}
@@ -136,11 +157,31 @@ public class ShadowUserManagerTest {
fail("Expected exception");
} catch (SecurityException expected) {}
- PackageInfo packageInfo = RuntimeEnvironment.application.getPackageManager()
- .getPackageInfo(RuntimeEnvironment.application.getPackageName(),
- PackageManager.GET_PERMISSIONS);
- packageInfo.requestedPermissions = new String[] { permission.MANAGE_USERS };
-
+ PackageInfo packageInfo =
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getPackageManager()
+ .getPackageInfo(
+ ((Application) ApplicationProvider.getApplicationContext()).getPackageName(),
+ GET_ACTIVITIES
+ | GET_CONFIGURATIONS
+ | GET_GIDS
+ | GET_INSTRUMENTATION
+ | GET_INTENT_FILTERS
+ | GET_META_DATA
+ | GET_PERMISSIONS
+ | GET_PROVIDERS
+ | GET_RECEIVERS
+ | GET_SERVICES
+ | GET_SHARED_LIBRARY_FILES
+ | GET_SIGNATURES
+ | GET_SIGNING_CERTIFICATES
+ | GET_URI_PERMISSION_PATTERNS
+ | GET_DISABLED_COMPONENTS
+ | GET_DISABLED_UNTIL_USED_COMPONENTS
+ | GET_UNINSTALLED_PACKAGES);
+ packageInfo.requestedPermissions = new String[] {permission.MANAGE_USERS};
+ shadowOf(((Application) ApplicationProvider.getApplicationContext()).getPackageManager())
+ .addPackage(packageInfo);
shadowOf(userManager).setManagedProfile(true);
assertThat(userManager.isManagedProfile()).isTrue();
@@ -173,19 +214,6 @@ public class ShadowUserManagerTest {
}
@Test
- @Config(minSdk = N_MR1)
- public void isAdminUser() {
- // All methods are based on the current user, so no need to pass a UserHandle.
- assertThat(userManager.isAdminUser()).isFalse();
-
- shadowOf(userManager).setIsAdminUser(true);
- assertThat(userManager.isAdminUser()).isTrue();
-
- shadowOf(userManager).setIsAdminUser(false);
- assertThat(userManager.isAdminUser()).isFalse();
- }
-
- @Test
@Config(minSdk = M)
public void isSystemUser() {
assertThat(userManager.isSystemUser()).isTrue();
@@ -285,6 +313,65 @@ public class ShadowUserManagerTest {
assertThat(userManager.isUserRunningOrStopping(userHandle)).isFalse();
}
+ @Test
+ @Config(minSdk = JELLY_BEAN_MR1)
+ public void addSecondaryUser() {
+ assertThat(userManager.getUserCount()).isEqualTo(1);
+ shadowOf(userManager).addUser(10, "secondary_user", 0);
+ assertThat(userManager.getUserCount()).isEqualTo(2);
+ }
+
+ @Test
+ @Config(minSdk = JELLY_BEAN_MR1)
+ public void removeSecondaryUser() {
+ shadowOf(userManager).addUser(10, "secondary_user", 0);
+ assertThat(shadowOf(userManager).removeUser(10)).isTrue();
+ assertThat(userManager.getUserCount()).isEqualTo(1);
+ }
+
+ @Test
+ @Config(minSdk = JELLY_BEAN_MR1)
+ public void switchToSecondaryUser() {
+ shadowOf(userManager).addUser(10, "secondary_user", 0);
+ shadowOf(userManager).switchUser(10);
+ assertThat(UserHandle.myUserId()).isEqualTo(10);
+ }
+
+ @Test
+ @Config(minSdk = N)
+ public void canSwitchUser() {
+ assertThat(shadowOf(userManager).canSwitchUsers()).isFalse();
+ shadowOf(userManager).setCanSwitchUser(true);
+ assertThat(shadowOf(userManager).canSwitchUsers()).isTrue();
+ }
+
+ @Test
+ @Config(minSdk = JELLY_BEAN_MR1)
+ public void getUsers() {
+ assertThat(userManager.getUsers()).hasSize(1);
+ shadowOf(userManager).addUser(10, "secondary_user", 0);
+ assertThat(userManager.getUsers()).hasSize(2);
+ }
+
+ @Test
+ @Config(minSdk = JELLY_BEAN_MR1)
+ public void getUserInfo() {
+ shadowOf(userManager).addUser(10, "secondary_user", 0);
+ assertThat(userManager.getUserInfo(10)).isNotNull();
+ assertThat(userManager.getUserInfo(10).name).isEqualTo("secondary_user");
+ }
+
+ @Test
+ @Config(minSdk = N)
+ public void switchToUserNotAddedShouldThrowException() {
+ try {
+ shadowOf(userManager).switchUser(10);
+ fail("Switching to the user that was never added should throw UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ assertThat(e).hasMessageThat().isEqualTo("Must add user before switching to it");
+ }
+ }
+
// Create user handle from parcel since UserHandle.of() was only added in later APIs.
private static UserHandle newUserHandle(int uid) {
Parcel userParcel = Parcel.obtain();
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowValueAnimatorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowValueAnimatorTest.java
index 5a7ef21b5..84157eeaf 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowValueAnimatorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowValueAnimatorTest.java
@@ -3,17 +3,17 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import android.animation.ValueAnimator;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.Ordering;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.util.TimeUtils;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowValueAnimatorTest {
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowVibratorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowVibratorTest.java
index 9e93bab13..caa00b75d 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowVibratorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowVibratorTest.java
@@ -4,23 +4,27 @@ import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.os.Vibrator;
+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.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowVibratorTest {
private Vibrator vibrator;
@Before
public void before() {
- vibrator = (Vibrator) RuntimeEnvironment.application.getSystemService(Context.VIBRATOR_SERVICE);
+ vibrator =
+ (Vibrator)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.VIBRATOR_SERVICE);
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowVideoViewTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowVideoViewTest.java
index 2899612eb..b413e51c0 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowVideoViewTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowVideoViewTest.java
@@ -3,22 +3,23 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.media.MediaPlayer;
import android.net.Uri;
import android.widget.VideoView;
+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 ShadowVideoViewTest {
private VideoView view;
@Before public void setUp() throws Exception {
- view = new VideoView(RuntimeEnvironment.application);
+ view = new VideoView((Application) ApplicationProvider.getApplicationContext());
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowViewAnimatorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowViewAnimatorTest.java
index a20355df1..0db67f697 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowViewAnimatorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowViewAnimatorTest.java
@@ -6,17 +6,17 @@ import static org.junit.Assert.assertSame;
import android.app.Application;
import android.view.View;
import android.widget.ViewAnimator;
+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 ShadowViewAnimatorTest {
ViewAnimator viewAnimator;
- final Application application = RuntimeEnvironment.application;
+ final Application application = (Application) ApplicationProvider.getApplicationContext();
@Before
public void setUp() {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowViewConfigurationTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowViewConfigurationTest.java
index 182095fa1..c7dd68a50 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowViewConfigurationTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowViewConfigurationTest.java
@@ -4,18 +4,20 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.view.ViewConfiguration;
+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 ShadowViewConfigurationTest {
@Test
public void methodsShouldReturnAndroidConstants() {
- ViewConfiguration viewConfiguration = ViewConfiguration.get(RuntimeEnvironment.application);
+ ViewConfiguration viewConfiguration =
+ ViewConfiguration.get((Application) ApplicationProvider.getApplicationContext());
assertEquals(10, ViewConfiguration.getScrollBarSize());
assertEquals(250, ViewConfiguration.getScrollBarFadeDuration());
@@ -36,7 +38,11 @@ public class ShadowViewConfigurationTest {
assertEquals(500, ViewConfiguration.getGlobalActionKeyTimeout());
assertThat(ViewConfiguration.getScrollFriction()).isEqualTo(0.015f);
- assertThat(RuntimeEnvironment.application.getResources().getDisplayMetrics().density)
+ assertThat(
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getDisplayMetrics()
+ .density)
.isEqualTo(1f);
assertEquals(10, viewConfiguration.getScaledScrollBarSize());
@@ -52,8 +58,13 @@ public class ShadowViewConfigurationTest {
@Test
public void methodsShouldReturnScaledAndroidConstantsDependingOnPixelDensity() {
- RuntimeEnvironment.application.getResources().getDisplayMetrics().density = 1.5f;
- ViewConfiguration viewConfiguration = ViewConfiguration.get(RuntimeEnvironment.application);
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getResources()
+ .getDisplayMetrics()
+ .density =
+ 1.5f;
+ ViewConfiguration viewConfiguration =
+ ViewConfiguration.get((Application) ApplicationProvider.getApplicationContext());
assertEquals(15, viewConfiguration.getScaledScrollBarSize());
assertEquals(18, viewConfiguration.getScaledFadingEdgeLength());
@@ -68,7 +79,8 @@ public class ShadowViewConfigurationTest {
@Test
public void testHasPermanentMenuKey() throws Exception {
- ViewConfiguration viewConfiguration = ViewConfiguration.get(RuntimeEnvironment.application);
+ ViewConfiguration viewConfiguration =
+ ViewConfiguration.get((Application) ApplicationProvider.getApplicationContext());
assertThat(viewConfiguration.hasPermanentMenuKey()).isFalse();
ShadowViewConfiguration shadowViewConfiguration = shadowOf(viewConfiguration);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowViewFlipperTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowViewFlipperTest.java
index d22e24312..a5ef97d21 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowViewFlipperTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowViewFlipperTest.java
@@ -2,20 +2,21 @@ package org.robolectric.shadows;
import static org.junit.Assert.assertEquals;
+import android.app.Application;
import android.widget.ViewFlipper;
+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 ShadowViewFlipperTest {
protected ViewFlipper flipper;
@Before
public void setUp() {
- flipper = new ViewFlipper(RuntimeEnvironment.application);
+ flipper = new ViewFlipper((Application) ApplicationProvider.getApplicationContext());
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowViewGroupTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowViewGroupTest.java
index 225d53861..05c10148e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowViewGroupTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowViewGroupTest.java
@@ -19,6 +19,8 @@ import android.view.animation.Animation.AnimationListener;
import android.view.animation.LayoutAnimationController;
import android.widget.FrameLayout;
import android.widget.TextView;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.After;
@@ -26,10 +28,8 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowViewGroupTest {
private String defaultLineSeparator;
private ViewGroup root;
@@ -42,7 +42,7 @@ public class ShadowViewGroupTest {
@Before
public void setUp() throws Exception {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
root = new FrameLayout(context);
@@ -245,8 +245,8 @@ public class ShadowViewGroupTest {
public void addViewWithLayoutParams_shouldStoreLayoutParams() throws Exception {
FrameLayout.LayoutParams layoutParams1 = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
FrameLayout.LayoutParams layoutParams2 = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- View child1 = new View(RuntimeEnvironment.application);
- View child2 = new View(RuntimeEnvironment.application);
+ View child1 = new View((Application) ApplicationProvider.getApplicationContext());
+ View child2 = new View((Application) ApplicationProvider.getApplicationContext());
root.addView(child1, layoutParams1);
root.addView(child2, 1, layoutParams2);
assertSame(layoutParams1, child1.getLayoutParams());
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowViewTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowViewTest.java
index 2d6b256f5..889a4f3af 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowViewTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowViewTest.java
@@ -16,6 +16,7 @@ import static org.robolectric.Robolectric.setupActivity;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
+import android.app.Application;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Point;
@@ -41,6 +42,8 @@ import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -49,8 +52,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.DeviceConfig;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.AccessibilityChecks;
@@ -58,7 +59,7 @@ import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.TestRunnable;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowViewTest {
private View view;
private List<String> transcript;
@@ -66,13 +67,13 @@ public class ShadowViewTest {
@Before
public void setUp() throws Exception {
transcript = new ArrayList<>();
- view = new View(RuntimeEnvironment.application);
+ view = new View((Application) ApplicationProvider.getApplicationContext());
}
@Test
public void testHasNullLayoutParamsUntilAddedToParent() throws Exception {
assertThat(view.getLayoutParams()).isNull();
- new LinearLayout(RuntimeEnvironment.application).addView(view);
+ new LinearLayout((Application) ApplicationProvider.getApplicationContext()).addView(view);
assertThat(view.getLayoutParams()).isNotNull();
}
@@ -88,23 +89,26 @@ public class ShadowViewTest {
@Test
public void measuredDimensions() throws Exception {
- View view1 = new View(RuntimeEnvironment.application) {
- {
- setMeasuredDimension(123, 456);
- }
- };
+ View view1 =
+ new View((Application) ApplicationProvider.getApplicationContext()) {
+ {
+ setMeasuredDimension(123, 456);
+ }
+ };
assertThat(view1.getMeasuredWidth()).isEqualTo(123);
assertThat(view1.getMeasuredHeight()).isEqualTo(456);
}
@Test
public void layout_shouldCallOnLayoutOnlyIfChanged() throws Exception {
- View view1 = new View(RuntimeEnvironment.application) {
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- transcript.add("onLayout " + changed + " " + left + " " + top + " " + right + " " + bottom);
- }
- };
+ View view1 =
+ new View((Application) ApplicationProvider.getApplicationContext()) {
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ transcript.add(
+ "onLayout " + changed + " " + left + " " + top + " " + right + " " + bottom);
+ }
+ };
view1.layout(0, 0, 0, 0);
assertThat(transcript).isEmpty();
view1.layout(1, 2, 3, 4);
@@ -141,7 +145,13 @@ public class ShadowViewTest {
assertThat(transcript).containsExactly("Gained focus");
transcript.clear();
- shadowOf(view).setMyParent(new LinearLayout(RuntimeEnvironment.application)); // we can never lose focus unless a parent can take it
+ shadowOf(view)
+ .setMyParent(
+ new LinearLayout(
+ (Application)
+ ApplicationProvider
+ .getApplicationContext())); // we can never lose focus unless a parent can
+ // take it
view.clearFocus();
assertFalse(view.isFocused());
@@ -164,10 +174,11 @@ public class ShadowViewTest {
assertThat(view.isShown()).isTrue();
shadowOf(view).setMyParent(null);
- ViewGroup parent = new LinearLayout(RuntimeEnvironment.application);
+ ViewGroup parent = new LinearLayout((Application) ApplicationProvider.getApplicationContext());
parent.addView(view);
- ViewGroup grandParent = new LinearLayout(RuntimeEnvironment.application);
+ ViewGroup grandParent =
+ new LinearLayout((Application) ApplicationProvider.getApplicationContext());
grandParent.addView(parent);
grandParent.setVisibility(View.GONE);
@@ -177,8 +188,9 @@ public class ShadowViewTest {
@Test
public void shouldInflateMergeRootedLayoutAndNotCreateReferentialLoops() throws Exception {
- LinearLayout root = new LinearLayout(RuntimeEnvironment.application);
- LinearLayout.inflate(RuntimeEnvironment.application, R.layout.inner_merge, root);
+ LinearLayout root = new LinearLayout((Application) ApplicationProvider.getApplicationContext());
+ LinearLayout.inflate(
+ (Application) ApplicationProvider.getApplicationContext(), R.layout.inner_merge, root);
for (int i = 0; i < root.getChildCount(); i++) {
View child = root.getChildAt(i);
assertNotSame(root, child);
@@ -207,8 +219,9 @@ public class ShadowViewTest {
@Test(expected = RuntimeException.class)
public void checkedClick_shouldThrowIfViewIsNotVisible() throws Exception {
- ViewGroup grandParent = new LinearLayout(RuntimeEnvironment.application);
- ViewGroup parent = new LinearLayout(RuntimeEnvironment.application);
+ ViewGroup grandParent =
+ new LinearLayout((Application) ApplicationProvider.getApplicationContext());
+ ViewGroup parent = new LinearLayout((Application) ApplicationProvider.getApplicationContext());
grandParent.addView(parent);
parent.addView(view);
grandParent.setVisibility(View.GONE);
@@ -328,9 +341,9 @@ public class ShadowViewTest {
@Test
public void shouldSupportAllConstructors() throws Exception {
- new View(RuntimeEnvironment.application);
- new View(RuntimeEnvironment.application, null);
- new View(RuntimeEnvironment.application, null, 0);
+ new View((Application) ApplicationProvider.getApplicationContext());
+ new View((Application) ApplicationProvider.getApplicationContext(), null);
+ new View((Application) ApplicationProvider.getApplicationContext(), null, 0);
}
@Test
@@ -348,7 +361,7 @@ public class ShadowViewTest {
.build()
;
- view = new View(RuntimeEnvironment.application, attrs);
+ view = new View((Application) ApplicationProvider.getApplicationContext(), attrs);
assertNotNull(shadowOf(view).getOnClickListener());
}
@@ -429,7 +442,8 @@ public class ShadowViewTest {
@Test
public void dispatchTouchEvent_sendsMotionEventToOnTouchEvent() throws Exception {
- TouchableView touchableView = new TouchableView(RuntimeEnvironment.application);
+ TouchableView touchableView =
+ new TouchableView((Application) ApplicationProvider.getApplicationContext());
MotionEvent event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 12f, 34f, 0);
touchableView.dispatchTouchEvent(event);
assertThat(touchableView.event).isSameAs(event);
@@ -952,7 +966,7 @@ public class ShadowViewTest {
private List<String> transcript;
public MyView(String name, List<String> transcript) {
- super(RuntimeEnvironment.application);
+ super((Application) ApplicationProvider.getApplicationContext());
this.name = name;
this.transcript = transcript;
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowVisualVoicemailSmsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowVisualVoicemailSmsTest.java
index 3cb797348..103be5b52 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowVisualVoicemailSmsTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowVisualVoicemailSmsTest.java
@@ -2,6 +2,7 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.os.Build.VERSION_CODES;
@@ -9,20 +10,20 @@ import android.os.Bundle;
import android.os.Parcel;
import android.telecom.PhoneAccountHandle;
import android.telephony.VisualVoicemailSms;
+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;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
/** Tests for {@link ShadowVisualVoicemailSms} */
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = VERSION_CODES.O)
public class ShadowVisualVoicemailSmsTest {
- private final Context appContext = RuntimeEnvironment.application;
+ private final Context appContext = (Application) ApplicationProvider.getApplicationContext();
private final PhoneAccountHandle phoneAccountHandle =
new PhoneAccountHandle(new ComponentName(appContext, Object.class), "foo");
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowWallpaperManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowWallpaperManagerTest.java
index 8a5b7610c..3652fa7f5 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowWallpaperManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowWallpaperManagerTest.java
@@ -2,24 +2,27 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import android.app.Application;
import android.app.WallpaperManager;
+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 ShadowWallpaperManagerTest {
@Test
public void getInstance_shouldCreateInstance() {
- WallpaperManager manager = WallpaperManager.getInstance(RuntimeEnvironment.application);
+ WallpaperManager manager =
+ WallpaperManager.getInstance((Application) ApplicationProvider.getApplicationContext());
assertThat(manager).isNotNull();
}
@Test
public void sendWallpaperCommand_shouldNotThrowException() {
- WallpaperManager manager = WallpaperManager.getInstance(RuntimeEnvironment.application);
+ WallpaperManager manager =
+ WallpaperManager.getInstance((Application) ApplicationProvider.getApplicationContext());
manager.sendWallpaperCommand(null, null, 0, 0, 0, null);
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowWebStorageTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowWebStorageTest.java
new file mode 100644
index 000000000..822fe71bf
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowWebStorageTest.java
@@ -0,0 +1,16 @@
+package org.robolectric.shadows;
+
+import android.webkit.WebStorage;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Tests for {@link ShadowWebStorage} */
+@RunWith(AndroidJUnit4.class)
+public final class ShadowWebStorageTest {
+
+ @Test
+ public void webStorageDoesNotCrash() throws Exception {
+ WebStorage.getInstance().deleteAllData();
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowWebViewTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowWebViewTest.java
index ed4d6f92d..b64523383 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowWebViewTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowWebViewTest.java
@@ -3,6 +3,8 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
+import android.content.pm.PackageInfo;
import android.os.Bundle;
import android.view.ViewGroup.LayoutParams;
import android.webkit.WebBackForwardList;
@@ -10,26 +12,23 @@ import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowWebViewTest {
private WebView webView;
- private ShadowWebView shadowWebView;
@Before
public void setUp() throws Exception {
- webView = new WebView(RuntimeEnvironment.application);
- shadowWebView = Shadows.shadowOf(webView);
+ webView = new WebView((Application) ApplicationProvider.getApplicationContext());
}
@Test
@@ -84,17 +83,17 @@ public class ShadowWebViewTest {
public void shouldRecordWebViewClient() {
WebViewClient webViewClient = new WebViewClient();
- assertThat(shadowWebView.getWebViewClient()).isNull();
+ assertThat(shadowOf(webView).getWebViewClient()).isNull();
webView.setWebViewClient(webViewClient);
- assertThat(shadowWebView.getWebViewClient()).isSameAs(webViewClient);
+ assertThat(shadowOf(webView).getWebViewClient()).isSameAs(webViewClient);
}
@Test
public void shouldRecordWebChromeClient() {
WebChromeClient webChromeClient = new WebChromeClient();
- assertThat(shadowWebView.getWebChromeClient()).isNull();
+ assertThat(shadowOf(webView).getWebChromeClient()).isNull();
webView.setWebChromeClient(webChromeClient);
- assertThat(shadowWebView.getWebChromeClient()).isSameAs(webChromeClient);
+ assertThat(shadowOf(webView).getWebChromeClient()).isSameAs(webChromeClient);
}
@Test
@@ -102,18 +101,18 @@ public class ShadowWebViewTest {
String[] names = {"name1", "name2"};
for (String name : names) {
Object obj = new Object();
- assertThat(shadowWebView.getJavascriptInterface(name)).isNull();
+ assertThat(shadowOf(webView).getJavascriptInterface(name)).isNull();
webView.addJavascriptInterface(obj, name);
- assertThat(shadowWebView.getJavascriptInterface(name)).isSameAs(obj);
+ assertThat(shadowOf(webView).getJavascriptInterface(name)).isSameAs(obj);
}
}
@Test
public void canGoBack() throws Exception {
- shadowWebView.clearHistory();
+ webView.clearHistory();
assertThat(webView.canGoBack()).isFalse();
- shadowWebView.loadUrl("fake.url", null);
- shadowWebView.loadUrl("fake.url", null);
+ webView.loadUrl("fake.url", null);
+ webView.loadUrl("fake.url", null);
assertThat(webView.canGoBack()).isTrue();
webView.goBack();
assertThat(webView.canGoBack()).isFalse();
@@ -121,77 +120,77 @@ public class ShadowWebViewTest {
@Test
public void shouldStoreTheNumberOfTimesGoBackWasCalled() throws Exception {
- assertThat(shadowWebView.getGoBackInvocations()).isEqualTo(0);
+ assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(0);
webView.goBack();
webView.loadUrl("foo.bar", null);
// If there is no history (only one page), we shouldn't invoke go back.
- assertThat(shadowWebView.getGoBackInvocations()).isEqualTo(0);
+ assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(0);
webView.loadUrl("foo.bar", null);
webView.loadUrl("foo.bar", null);
webView.loadUrl("foo.bar", null);
webView.loadUrl("foo.bar", null);
webView.loadUrl("foo.bar", null);
webView.goBack();
- assertThat(shadowWebView.getGoBackInvocations()).isEqualTo(1);
+ assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(1);
webView.goBack();
webView.goBack();
- assertThat(shadowWebView.getGoBackInvocations()).isEqualTo(3);
+ assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(3);
webView.goBack();
webView.goBack();
webView.goBack();
// We've gone back one too many times for the history, so we should only have 5 invocations.
- assertThat(shadowWebView.getGoBackInvocations()).isEqualTo(5);
+ assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(5);
}
@Test
public void shouldStoreTheNumberOfTimesGoBackWasCalled_SetCanGoBack() {
- shadowWebView.setCanGoBack(true);
+ shadowOf(webView).setCanGoBack(true);
webView.goBack();
webView.goBack();
- assertThat(shadowWebView.getGoBackInvocations()).isEqualTo(2);
- shadowWebView.setCanGoBack(false);
+ assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(2);
+ shadowOf(webView).setCanGoBack(false);
webView.goBack();
webView.goBack();
- assertThat(shadowWebView.getGoBackInvocations()).isEqualTo(2);
+ assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(2);
}
@Test
public void shouldRecordClearCacheWithoutDiskFiles() {
- assertThat(shadowWebView.wasClearCacheCalled()).isFalse();
+ assertThat(shadowOf(webView).wasClearCacheCalled()).isFalse();
webView.clearCache(false);
- assertThat(shadowWebView.wasClearCacheCalled()).isTrue();
- assertThat(shadowWebView.didClearCacheIncludeDiskFiles()).isFalse();
+ assertThat(shadowOf(webView).wasClearCacheCalled()).isTrue();
+ assertThat(shadowOf(webView).didClearCacheIncludeDiskFiles()).isFalse();
}
@Test
public void shouldRecordClearCacheWithDiskFiles() {
- assertThat(shadowWebView.wasClearCacheCalled()).isFalse();
+ assertThat(shadowOf(webView).wasClearCacheCalled()).isFalse();
webView.clearCache(true);
- assertThat(shadowWebView.wasClearCacheCalled()).isTrue();
- assertThat(shadowWebView.didClearCacheIncludeDiskFiles()).isTrue();
+ assertThat(shadowOf(webView).wasClearCacheCalled()).isTrue();
+ assertThat(shadowOf(webView).didClearCacheIncludeDiskFiles()).isTrue();
}
@Test
public void shouldRecordClearFormData() {
- assertThat(shadowWebView.wasClearFormDataCalled()).isFalse();
+ assertThat(shadowOf(webView).wasClearFormDataCalled()).isFalse();
webView.clearFormData();
- assertThat(shadowWebView.wasClearFormDataCalled()).isTrue();
+ assertThat(shadowOf(webView).wasClearFormDataCalled()).isTrue();
}
@Test
public void shouldRecordClearHistory() {
- assertThat(shadowWebView.wasClearHistoryCalled()).isFalse();
+ assertThat(shadowOf(webView).wasClearHistoryCalled()).isFalse();
webView.clearHistory();
- assertThat(shadowWebView.wasClearHistoryCalled()).isTrue();
+ assertThat(shadowOf(webView).wasClearHistoryCalled()).isTrue();
}
@Test
public void shouldRecordClearView() {
- assertThat(shadowWebView.wasClearViewCalled()).isFalse();
+ assertThat(shadowOf(webView).wasClearViewCalled()).isFalse();
webView.clearView();
- assertThat(shadowWebView.wasClearViewCalled()).isTrue();
+ assertThat(shadowOf(webView).wasClearViewCalled()).isTrue();
}
@Test
@@ -213,30 +212,30 @@ public class ShadowWebViewTest {
@Test
@Config(minSdk = 19)
public void evaluateJavascript() {
- assertThat(shadowWebView.getLastEvaluatedJavascript()).isNull();
+ assertThat(shadowOf(webView).getLastEvaluatedJavascript()).isNull();
webView.evaluateJavascript("myScript", null);
- assertThat(shadowWebView.getLastEvaluatedJavascript()).isEqualTo("myScript");
+ assertThat(shadowOf(webView).getLastEvaluatedJavascript()).isEqualTo("myScript");
}
@Test
public void shouldRecordDestroy() {
- assertThat(shadowWebView.wasDestroyCalled()).isFalse();
+ assertThat(shadowOf(webView).wasDestroyCalled()).isFalse();
webView.destroy();
- assertThat(shadowWebView.wasDestroyCalled()).isTrue();
+ assertThat(shadowOf(webView).wasDestroyCalled()).isTrue();
}
@Test
public void shouldRecordOnPause() {
- assertThat(shadowWebView.wasOnPauseCalled()).isFalse();
+ assertThat(shadowOf(webView).wasOnPauseCalled()).isFalse();
webView.onPause();
- assertThat(shadowWebView.wasOnPauseCalled()).isTrue();
+ assertThat(shadowOf(webView).wasOnPauseCalled()).isTrue();
}
@Test
public void shouldRecordOnResume() {
- assertThat(shadowWebView.wasOnResumeCalled()).isFalse();
+ assertThat(shadowOf(webView).wasOnResumeCalled()).isFalse();
webView.onResume();
- assertThat(shadowWebView.wasOnResumeCalled()).isTrue();
+ assertThat(shadowOf(webView).wasOnResumeCalled()).isTrue();
}
@Test
@@ -255,7 +254,7 @@ public class ShadowWebViewTest {
Bundle outState = new Bundle();
webView.saveState(outState);
- WebView newWebView = new WebView(RuntimeEnvironment.application);
+ WebView newWebView = new WebView((Application) ApplicationProvider.getApplicationContext());
WebBackForwardList historyList = newWebView.restoreState(outState);
assertThat(newWebView.canGoBack()).isTrue();
@@ -284,4 +283,52 @@ public class ShadowWebViewTest {
assertThat(historyList).isNull();
}
+
+ @Test
+ public void shouldCopyBackForwardListWhenEmpty() {
+ WebBackForwardList historyList = webView.copyBackForwardList();
+
+ assertThat(historyList.getSize()).isEqualTo(0);
+ assertThat(historyList.getCurrentIndex()).isEqualTo(-1);
+ assertThat(historyList.getCurrentItem()).isNull();
+ }
+
+ @Test
+ public void shouldCopyBackForwardListWhenPopulated() {
+ webView.loadUrl("foo1.bar");
+ webView.loadUrl("foo2.bar");
+
+ WebBackForwardList historyList = webView.copyBackForwardList();
+
+ assertThat(historyList.getSize()).isEqualTo(2);
+ assertThat(historyList.getCurrentItem().getUrl()).isEqualTo("foo2.bar");
+ }
+
+ @Test
+ public void shouldReturnCopyFromCopyBackForwardList() {
+ WebBackForwardList historyList = webView.copyBackForwardList();
+
+ // Adding history after copying should not affect the copy.
+ webView.loadUrl("foo1.bar");
+ webView.loadUrl("foo2.bar");
+
+ assertThat(historyList.getSize()).isEqualTo(0);
+ assertThat(historyList.getCurrentIndex()).isEqualTo(-1);
+ assertThat(historyList.getCurrentItem()).isNull();
+ }
+
+ @Test
+ @Config(minSdk = 26)
+ public void shouldReturnNullForGetCurrentWebViewPackageIfNotSet() {
+ assertThat(WebView.getCurrentWebViewPackage()).isNull();
+ }
+
+ @Test
+ @Config(minSdk = 26)
+ public void shouldReturnStoredPackageInfoForGetCurrentWebViewPackageIfSet() {
+ PackageInfo packageInfo = new PackageInfo();
+ packageInfo.packageName = "org.robolectric.shadows.shadowebviewtest";
+ ShadowWebView.setCurrentWebViewPackage(packageInfo);
+ assertThat(WebView.getCurrentWebViewPackage()).isEqualTo(packageInfo);
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiConfigurationTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiConfigurationTest.java
index 541daead5..f47f652ea 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiConfigurationTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiConfigurationTest.java
@@ -7,12 +7,12 @@ import static org.robolectric.Shadows.shadowOf;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.os.Build;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowWifiConfigurationTest {
@Test
public void shouldSetTheBitSetsAndWepKeyArrays() throws Exception {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiInfoTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiInfoTest.java
index 377f4b1b1..0a5d06a3b 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiInfoTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiInfoTest.java
@@ -8,14 +8,14 @@ import static org.robolectric.Shadows.shadowOf;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.net.InetAddress;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowWifiInfoTest {
private WifiManager wifiManager;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiManagerTest.java
index 266afda09..82490674b 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiManagerTest.java
@@ -6,6 +6,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
@@ -17,18 +18,20 @@ import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.MulticastLock;
import android.os.Build;
import android.util.Pair;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowWifiManagerTest {
- private final WifiManager wifiManager = (WifiManager) RuntimeEnvironment.application.getSystemService(Context.WIFI_SERVICE);
- private final ShadowWifiManager shadowWifiManager = shadowOf(wifiManager);
+ private final WifiManager wifiManager =
+ (WifiManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.WIFI_SERVICE);
@Test
public void shouldReturnWifiInfo() {
@@ -38,32 +41,57 @@ public class ShadowWifiManagerTest {
@Test
public void setWifiInfo_shouldUpdateWifiInfo() {
WifiInfo wifiInfo = new WifiInfo();
- shadowWifiManager.setConnectionInfo(wifiInfo);
+ shadowOf(wifiManager).setConnectionInfo(wifiInfo);
assertThat(wifiManager.getConnectionInfo()).isSameAs(wifiInfo);
}
- @Test(expected = SecurityException.class)
- public void setWifiEnabled_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted() throws Exception {
- shadowWifiManager.setAccessWifiStatePermission(false);
- wifiManager.setWifiEnabled(true);
+ @Test
+ public void setWifiEnabled_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted()
+ throws Exception {
+ shadowOf(wifiManager).setAccessWifiStatePermission(false);
+ try {
+ wifiManager.setWifiEnabled(true);
+ fail("SecurityException not thrown");
+ } catch (SecurityException e) {
+ // expected
+ }
}
- @Test(expected = SecurityException.class)
- public void isWifiEnabled_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted() throws Exception {
- shadowWifiManager.setAccessWifiStatePermission(false);
- wifiManager.isWifiEnabled();
+ @Test
+ public void isWifiEnabled_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted()
+ throws Exception {
+ shadowOf(wifiManager).setAccessWifiStatePermission(false);
+ try {
+ wifiManager.isWifiEnabled();
+ fail("SecurityException not thrown");
+ } catch (SecurityException e) {
+ // expected
+ }
}
- @Test(expected = SecurityException.class)
- public void getWifiState_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted() throws Exception {
- shadowWifiManager.setAccessWifiStatePermission(false);
- wifiManager.getWifiState();
+ @Test
+ public void getWifiState_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted()
+ throws Exception {
+ shadowOf(wifiManager).setAccessWifiStatePermission(false);
+ try {
+ wifiManager.getWifiState();
+ fail("SecurityException not thrown");
+ } catch (SecurityException e) {
+ // expected
+ }
}
- @Test(expected = SecurityException.class)
- public void getConnectionInfo_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted() throws Exception {
- shadowWifiManager.setAccessWifiStatePermission(false);
- wifiManager.getConnectionInfo();
+ @Test
+ public void
+ getConnectionInfo_shouldThrowSecurityExceptionWhenAccessWifiStatePermissionNotGranted()
+ throws Exception {
+ shadowOf(wifiManager).setAccessWifiStatePermission(false);
+ try {
+ wifiManager.getConnectionInfo();
+ fail("SecurityException not thrown");
+ } catch (SecurityException e) {
+ // expected
+ }
}
@Test
@@ -80,45 +108,45 @@ public class ShadowWifiManagerTest {
// By default startScan() succeeds.
assertThat(wifiManager.startScan()).isTrue();
- shadowWifiManager.setStartScanSucceeds(true);
+ shadowOf(wifiManager).setStartScanSucceeds(true);
assertThat(wifiManager.startScan()).isTrue();
- shadowWifiManager.setStartScanSucceeds(false);
+ shadowOf(wifiManager).setStartScanSucceeds(false);
assertThat(wifiManager.startScan()).isFalse();
}
@Test
@Config(minSdk = JELLY_BEAN_MR2)
public void getIsScanAlwaysAvailable() {
- shadowWifiManager.setIsScanAlwaysAvailable(true);
+ shadowOf(wifiManager).setIsScanAlwaysAvailable(true);
assertThat(wifiManager.isScanAlwaysAvailable()).isEqualTo(true);
- shadowWifiManager.setIsScanAlwaysAvailable(false);
+ shadowOf(wifiManager).setIsScanAlwaysAvailable(false);
assertThat(wifiManager.isScanAlwaysAvailable()).isEqualTo(false);
}
@Test
public void shouldEnableNetworks() throws Exception {
wifiManager.enableNetwork(666, true);
- Pair<Integer, Boolean> lastEnabled = shadowWifiManager.getLastEnabledNetwork();
+ Pair<Integer, Boolean> lastEnabled = shadowOf(wifiManager).getLastEnabledNetwork();
assertThat(lastEnabled).isEqualTo(new Pair<>(666, true));
wifiManager.enableNetwork(777, false);
- lastEnabled = shadowWifiManager.getLastEnabledNetwork();
+ lastEnabled = shadowOf(wifiManager).getLastEnabledNetwork();
assertThat(lastEnabled).isEqualTo(new Pair<>(777, false));
}
@Test
public void shouldReturnSetScanResults() throws Exception {
List<ScanResult> scanResults = new ArrayList<>();
- shadowWifiManager.setScanResults(scanResults);
+ shadowOf(wifiManager).setScanResults(scanResults);
assertThat(wifiManager.getScanResults()).isSameAs(scanResults);
}
@Test
public void shouldReturnDhcpInfo() {
DhcpInfo dhcpInfo = new DhcpInfo();
- shadowWifiManager.setDhcpInfo(dhcpInfo);
+ shadowOf(wifiManager).setDhcpInfo(dhcpInfo);
assertThat(wifiManager.getDhcpInfo()).isSameAs(dhcpInfo);
}
@@ -203,7 +231,7 @@ public class ShadowWifiManagerTest {
@Test
public void shouldSaveConfigurations() throws Exception {
assertThat(wifiManager.saveConfiguration()).isTrue();
- assertThat(shadowWifiManager.wasConfigurationSaved()).isTrue();
+ assertThat(shadowOf(wifiManager).wasConfigurationSaved()).isTrue();
}
@Test
@@ -213,6 +241,26 @@ public class ShadowWifiManagerTest {
}
@Test
+ public void wifiLockAcquireIncreasesActiveLockCount() throws Exception {
+ WifiManager.WifiLock lock = wifiManager.createWifiLock("TAG");
+ assertThat(shadowOf(wifiManager).getActiveLockCount()).isEqualTo(0);
+ lock.acquire();
+ assertThat(shadowOf(wifiManager).getActiveLockCount()).isEqualTo(1);
+ lock.release();
+ assertThat(shadowOf(wifiManager).getActiveLockCount()).isEqualTo(0);
+ }
+
+ @Test
+ public void multicastLockAcquireIncreasesActiveLockCount() throws Exception {
+ MulticastLock lock = wifiManager.createMulticastLock("TAG");
+ assertThat(shadowOf(wifiManager).getActiveLockCount()).isEqualTo(0);
+ lock.acquire();
+ assertThat(shadowOf(wifiManager).getActiveLockCount()).isEqualTo(1);
+ lock.release();
+ assertThat(shadowOf(wifiManager).getActiveLockCount()).isEqualTo(0);
+ }
+
+ @Test
public void shouldAcquireAndReleaseWifilockRefCounted() throws Exception {
WifiManager.WifiLock lock = wifiManager.createWifiLock("TAG");
lock.acquire();
@@ -236,17 +284,27 @@ public class ShadowWifiManagerTest {
assertThat(lock.isHeld()).isFalse();
}
- @Test(expected = RuntimeException.class)
+ @Test
public void shouldThrowRuntimeExceptionIfWifiLockisUnderlocked() throws Exception {
WifiManager.WifiLock lock = wifiManager.createWifiLock("TAG");
- lock.release();
+ try {
+ lock.release();
+ fail("RuntimeException not thrown");
+ } catch (RuntimeException e) {
+ // expected
+ }
}
- @Test(expected = UnsupportedOperationException.class)
+ @Test
public void shouldThrowUnsupportedOperationIfWifiLockisOverlocked() throws Exception {
WifiManager.WifiLock lock = wifiManager.createWifiLock("TAG");
- for (int i = 0; i < ShadowWifiManager.ShadowWifiLock.MAX_ACTIVE_LOCKS; i++) {
- lock.acquire();
+ try {
+ for (int i = 0; i < ShadowWifiManager.ShadowWifiLock.MAX_ACTIVE_LOCKS; i++) {
+ lock.acquire();
+ }
+ fail("UnsupportedOperationException not thrown");
+ } catch (UnsupportedOperationException e) {
+ // expected
}
}
@@ -384,7 +442,8 @@ public class ShadowWifiManagerTest {
// THEN
NetworkInfo networkInfo =
((ConnectivityManager)
- RuntimeEnvironment.application.getSystemService(Context.CONNECTIVITY_SERVICE))
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.CONNECTIVITY_SERVICE))
.getActiveNetworkInfo();
assertThat(networkInfo.getType()).isEqualTo(ConnectivityManager.TYPE_WIFI);
assertThat(networkInfo.isConnected()).isTrue();
@@ -392,6 +451,16 @@ public class ShadowWifiManagerTest {
@Test
@Config(minSdk = Build.VERSION_CODES.KITKAT)
+ public void connect_setsNetworkId_shouldHasNetworkId() throws Exception {
+ // WHEN
+ wifiManager.connect(123, null);
+
+ // THEN
+ assertThat(wifiManager.getConnectionInfo().getNetworkId()).isEqualTo(123);
+ }
+
+ @Test
+ @Config(minSdk = Build.VERSION_CODES.KITKAT)
public void connect_setsConnectionInfo() throws Exception {
// GIVEN
WifiConfiguration wifiConfiguration = new WifiConfiguration();
@@ -408,7 +477,7 @@ public class ShadowWifiManagerTest {
@Config(minSdk = LOLLIPOP)
public void is5GhzBandSupportedAndConfigurable() throws Exception {
assertThat(wifiManager.is5GHzBandSupported()).isFalse();
- shadowWifiManager.setIs5GHzBandSupported(true);
+ shadowOf(wifiManager).setIs5GHzBandSupported(true);
assertThat(wifiManager.is5GHzBandSupported()).isTrue();
}
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiP2pManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiP2pManagerTest.java
index a62281c7b..985c8dd65 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiP2pManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiP2pManagerTest.java
@@ -3,18 +3,20 @@ package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pManager;
+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.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowWifiP2pManagerTest {
private WifiP2pManager manager;
@@ -25,9 +27,16 @@ public class ShadowWifiP2pManagerTest {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- manager = (WifiP2pManager) RuntimeEnvironment.application.getSystemService(Context.WIFI_P2P_SERVICE);
+ manager =
+ (WifiP2pManager)
+ ((Application) ApplicationProvider.getApplicationContext())
+ .getSystemService(Context.WIFI_P2P_SERVICE);
shadowManager = shadowOf(manager);
- channel = manager.initialize(RuntimeEnvironment.application, RuntimeEnvironment.application.getMainLooper(), mockListener);
+ channel =
+ manager.initialize(
+ (Application) ApplicationProvider.getApplicationContext(),
+ ((Application) ApplicationProvider.getApplicationContext()).getMainLooper(),
+ mockListener);
assertThat(channel).isNotNull();
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowWindowManagerGlobalTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowWindowManagerGlobalTest.java
index d12e7867d..53a87ede7 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowWindowManagerGlobalTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowWindowManagerGlobalTest.java
@@ -4,12 +4,12 @@ import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static com.google.common.truth.Truth.assertThat;
import android.os.Looper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
@Config(minSdk = JELLY_BEAN_MR1)
public class ShadowWindowManagerGlobalTest {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowWindowManagerImplTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowWindowManagerImplTest.java
new file mode 100644
index 000000000..bf9dcbd91
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowWindowManagerImplTest.java
@@ -0,0 +1,70 @@
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.O;
+import static com.google.common.truth.Truth.assertThat;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+/** Unit test for {@link ShadowWindowManagerImpl}. */
+@RunWith(AndroidJUnit4.class)
+@Config(minSdk = O)
+public class ShadowWindowManagerImplTest {
+
+ private View view;
+ private LayoutParams layoutParams;
+ private WindowManager windowManager;
+
+ @Before
+ public void setUp() {
+ Context context = ApplicationProvider.getApplicationContext();
+ view = new View(context);
+ windowManager = context.getSystemService(WindowManager.class);
+ layoutParams =
+ new LayoutParams(
+ /*w=*/ ViewGroup.LayoutParams.MATCH_PARENT,
+ /*h=*/ ViewGroup.LayoutParams.MATCH_PARENT,
+ LayoutParams.TYPE_APPLICATION_OVERLAY,
+ LayoutParams.FLAG_LAYOUT_IN_SCREEN,
+ PixelFormat.TRANSLUCENT);
+ }
+
+ @Test
+ public void getViews_isInitiallyEmpty() {
+ List<View> views = ((ShadowWindowManagerImpl) shadowOf(windowManager)).getViews();
+
+ assertThat(views).isEmpty();
+ }
+
+ @Test
+ public void getViews_returnsAnAddedView() {
+ windowManager.addView(view, layoutParams);
+
+ List<View> views = ((ShadowWindowManagerImpl) shadowOf(windowManager)).getViews();
+
+ assertThat(views).hasSize(1);
+ assertThat(views.get(0)).isSameAs(view);
+ }
+
+ @Test
+ public void getViews_doesNotReturnARemovedView() {
+ windowManager.addView(view, layoutParams);
+ windowManager.removeView(view);
+
+ List<View> views = ((ShadowWindowManagerImpl) shadowOf(windowManager)).getViews();
+
+ assertThat(views).isEmpty();
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowWindowTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowWindowTest.java
index e2dfccf99..5b4b055a7 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowWindowTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowWindowTest.java
@@ -7,21 +7,22 @@ import static org.robolectric.Shadows.shadowOf;
import android.R;
import android.app.Activity;
+import android.app.Application;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
+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.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ShadowWindowTest {
@Test
public void getFlag_shouldReturnWindowFlags() throws Exception {
@@ -97,13 +98,19 @@ public class ShadowWindowTest {
@Test @Config(maxSdk = LOLLIPOP_MR1)
public void forPreM_create_shouldCreateImplPhoneWindow() throws Exception {
- assertThat(ShadowWindow.create(RuntimeEnvironment.application).getClass().getName())
+ assertThat(
+ ShadowWindow.create((Application) ApplicationProvider.getApplicationContext())
+ .getClass()
+ .getName())
.isEqualTo("com.android.internal.policy.impl.PhoneWindow");
}
@Test @Config(minSdk = M)
public void forM_create_shouldCreatePhoneWindow() throws Exception {
- assertThat(ShadowWindow.create(RuntimeEnvironment.application).getClass().getName())
+ assertThat(
+ ShadowWindow.create((Application) ApplicationProvider.getApplicationContext())
+ .getClass()
+ .getName())
.isEqualTo("com.android.internal.policy.PhoneWindow");
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/VelocityTrackerTest.java b/robolectric/src/test/java/org/robolectric/shadows/VelocityTrackerTest.java
index 90c5fcefd..747bb3bda 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/VelocityTrackerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/VelocityTrackerTest.java
@@ -4,13 +4,13 @@ import static com.google.common.truth.Truth.assertThat;
import android.view.MotionEvent;
import android.view.VelocityTracker;
+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.Shadows;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class VelocityTrackerTest {
VelocityTracker velocityTracker;
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ViewInnerTextTest.java b/robolectric/src/test/java/org/robolectric/shadows/ViewInnerTextTest.java
index c4d2f35a4..ef67e6e72 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ViewInnerTextTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ViewInnerTextTest.java
@@ -3,23 +3,24 @@ package org.robolectric.shadows;
import static org.junit.Assert.assertEquals;
import static org.robolectric.Shadows.shadowOf;
+import android.app.Application;
import android.content.Context;
import android.view.View;
import android.widget.LinearLayout;
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 ViewInnerTextTest {
private Context context;
@Before
public void setUp() throws Exception {
- context = RuntimeEnvironment.application;
+ context = (Application) ApplicationProvider.getApplicationContext();
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ViewStubTest.java b/robolectric/src/test/java/org/robolectric/shadows/ViewStubTest.java
index f33934031..890673d4f 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ViewStubTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ViewStubTest.java
@@ -6,24 +6,25 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
+import android.app.Application;
import android.content.Context;
import android.view.View;
import android.view.ViewStub;
import android.widget.LinearLayout;
+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.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ViewStubTest {
private Context ctxt;
@Before public void setUp() throws Exception {
- ctxt = RuntimeEnvironment.application;
+ ctxt = (Application) ApplicationProvider.getApplicationContext();
}
@Test
diff --git a/robolectric/src/test/java/org/robolectric/shadows/XmlPullParserTest.java b/robolectric/src/test/java/org/robolectric/shadows/XmlPullParserTest.java
index a8e667bf6..261c181c3 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/XmlPullParserTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/XmlPullParserTest.java
@@ -4,8 +4,11 @@ import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.res.android.ResourceTypes.ANDROID_NS;
import static org.robolectric.res.android.ResourceTypes.AUTO_NS;
+import android.app.Application;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -13,12 +16,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.R;
import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class XmlPullParserTest {
// emulator output:
@@ -34,7 +36,8 @@ http://schemas.android.com/apk/res-auto:title(resId=2130771971) type=CDATA: valu
@Test
public void xmlParser() throws IOException, XmlPullParserException {
- Resources resources = RuntimeEnvironment.application.getResources();
+ Resources resources =
+ ((Application) ApplicationProvider.getApplicationContext()).getResources();
XmlResourceParser parser = resources.getXml(R.xml.xml_attrs);
assertThat(parser).isNotNull();
diff --git a/robolectric/src/test/java/org/robolectric/util/SQLiteLibraryLoaderTest.java b/robolectric/src/test/java/org/robolectric/util/SQLiteLibraryLoaderTest.java
index c9b8ade6f..a46708103 100644
--- a/robolectric/src/test/java/org/robolectric/util/SQLiteLibraryLoaderTest.java
+++ b/robolectric/src/test/java/org/robolectric/util/SQLiteLibraryLoaderTest.java
@@ -2,15 +2,15 @@ package org.robolectric.util;
import static com.google.common.truth.Truth.assertThat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.io.IOException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.util.SQLiteLibraryLoader;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class SQLiteLibraryLoaderTest {
/** Saved system properties. */
private String savedOs, savedArch;
diff --git a/robolectric/src/test/resources/AndroidManifest.xml b/robolectric/src/test/resources/AndroidManifest.xml
index 5fb7dda1e..5ba014f13 100644
--- a/robolectric/src/test/resources/AndroidManifest.xml
+++ b/robolectric/src/test/resources/AndroidManifest.xml
@@ -126,6 +126,8 @@
</intent-filter>
</activity>
+ <activity android:name="org.robolectric.shadows.DisabledActivity" android:enabled="false"/>
+
<activity-alias
android:name="org.robolectric.shadows.TestActivityAlias"
android:targetActivity=".shadows.TestActivity">
@@ -140,11 +142,14 @@
<action android:name="org.robolectric.ACTION_DIFFERENT_PACKAGE"/>
<data android:mimeType="image/jpeg"/>
<category android:name="android.intent.category.LAUNCHER"/>
- </intent-filter> <meta-data android:name="metadatasample" android:value="sample"/>
+ </intent-filter>
+ <meta-data android:name="metadatasample" android:value="sample"/>
</service>
<service android:name="com.bar.ServiceWithoutIntentFilter"/>
+ <service android:name="org.robolectric.shadows.DisabledService" android:enabled="false"/>
+
<!-- Fully qualified name reference -->
<provider
android:name="org.robolectric.shadows.testing.TestContentProvider1"
diff --git a/robolectric/src/test/resources/TestAndroidManifestWithContentProviders.xml b/robolectric/src/test/resources/TestAndroidManifestWithContentProviders.xml
index a6c9eaf58..78c51ebcf 100644
--- a/robolectric/src/test/resources/TestAndroidManifestWithContentProviders.xml
+++ b/robolectric/src/test/resources/TestAndroidManifestWithContentProviders.xml
@@ -8,7 +8,8 @@
<provider
android:name=".tester.PartiallyQualifiedClassName"
- android:authorities="org.robolectric.authority2"/>
+ android:authorities="org.robolectric.authority2"
+ android:enabled="false"/>
<provider
android:name="org.robolectric.android.controller.ContentProviderControllerTest$MyContentProvider"
diff --git a/robolectric/src/test/resources/TestAndroidManifestWithReceivers.xml b/robolectric/src/test/resources/TestAndroidManifestWithReceivers.xml
index a8f8139ff..95120e276 100644
--- a/robolectric/src/test/resources/TestAndroidManifestWithReceivers.xml
+++ b/robolectric/src/test/resources/TestAndroidManifestWithReceivers.xml
@@ -33,7 +33,7 @@
</intent-filter>
</receiver>
- <receiver android:name=".test.ConfigTestReceiver">
+ <receiver android:name=".test.ConfigTestReceiver" android:enabled="false">
<intent-filter>
<action android:name="org.robolectric.ACTION_DOT_SUBPACKAGE"/>
</intent-filter>
diff --git a/robolectric/src/test/resources/TestAndroidManifestWithServices.xml b/robolectric/src/test/resources/TestAndroidManifestWithServices.xml
index bd1c1311f..3322d9d56 100644
--- a/robolectric/src/test/resources/TestAndroidManifestWithServices.xml
+++ b/robolectric/src/test/resources/TestAndroidManifestWithServices.xml
@@ -10,6 +10,6 @@
</intent-filter>
</service>
- <service android:name="com.bar.ServiceWithoutIntentFilter"/>
+ <service android:name="com.bar.ServiceWithoutIntentFilter" android:enabled="false"/>
</application>
</manifest>
diff --git a/robolectric/src/test/resources/res/values/ids.xml b/robolectric/src/test/resources/res/values/ids.xml
index 7144911e1..a70cfe362 100644
--- a/robolectric/src/test/resources/res/values/ids.xml
+++ b/robolectric/src/test/resources/res/values/ids.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="id_declared_in_item_tag" type="id"/>
- <item name="id_with_string_value" type="id">string value</item>
+ <item name="id_with_string_value" type="id"/>
<item name="declared_id" type="id"/>
-</resources> \ No newline at end of file
+</resources>
diff --git a/robolectric/src/test/resources/res/values/plurals.xml b/robolectric/src/test/resources/res/values/plurals.xml
index 95dc456e6..823968a14 100644
--- a/robolectric/src/test/resources/res/values/plurals.xml
+++ b/robolectric/src/test/resources/res/values/plurals.xml
@@ -5,10 +5,8 @@
In us-en locale, only one and other plurals are used because there are only two possible
variants: singular vs plural tense.
-->
- <item quantity="zero">unused</item>
- <item quantity="one">beer</item>
- <item quantity="two">unused</item>
- <item quantity="other">beers</item>
+ <item quantity="one">a beer</item>
+ <item quantity="other">some beers</item>
</plurals>
<plurals name="minute">
<item quantity="one">@string/minute_singular</item>
diff --git a/robolectric/src/test/resources/resources.ap_ b/robolectric/src/test/resources/resources.ap_
index 347ef1573..2f7b7f89f 100644
--- a/robolectric/src/test/resources/resources.ap_
+++ b/robolectric/src/test/resources/resources.ap_
Binary files differ
diff --git a/sandbox/build.gradle b/sandbox/build.gradle
index 23a27d006..5223a6b08 100644
--- a/sandbox/build.gradle
+++ b/sandbox/build.gradle
@@ -1,24 +1,19 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
dependencies {
- // Compile dependencies
- compile project(":annotations")
- compile project(":utils")
- compile project(":shadowapi")
+ api project(":annotations")
+ api project(":utils")
+ api project(":shadowapi")
- compile "org.ow2.asm:asm:6.0"
- compile "org.ow2.asm:asm-commons:6.0"
- compile "com.google.guava:guava:20.0"
- compileOnly "com.google.code.findbugs:jsr305:3.0.1"
+ api "org.ow2.asm:asm:7.0"
+ api "org.ow2.asm:asm-commons:7.0"
+ api "com.google.guava:guava:20.0"
+ compileOnly "com.google.code.findbugs:jsr305:3.0.2"
- testCompile "junit:junit:4.12"
- testCompile "com.google.truth:truth:0.39"
- testCompile "org.mockito:mockito-core:2.5.4"
- testCompile project(":junit")
+ testImplementation "junit:junit:4.12"
+ testImplementation "com.google.truth:truth:0.42"
+ testImplementation "org.mockito:mockito-core:2.5.4"
+ testImplementation project(":junit")
} \ No newline at end of file
diff --git a/sandbox/src/main/java/org/robolectric/internal/bytecode/ClassInstrumentor.java b/sandbox/src/main/java/org/robolectric/internal/bytecode/ClassInstrumentor.java
index 3fe6d77de..8997be4b2 100644
--- a/sandbox/src/main/java/org/robolectric/internal/bytecode/ClassInstrumentor.java
+++ b/sandbox/src/main/java/org/robolectric/internal/bytecode/ClassInstrumentor.java
@@ -2,7 +2,6 @@ package org.robolectric.internal.bytecode;
import java.lang.invoke.MethodType;
import java.lang.reflect.Modifier;
-import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import org.objectweb.asm.ClassReader;
@@ -191,32 +190,6 @@ public abstract class ClassInstrumentor {
}
}
- /**
- * Checks if the given method would override a final method in a superclass. This isn't possible
- * at compile time but could have occurred with a synthetic method.
- */
- private boolean isOverridingFinalMethod(MutableClass mutableClass, String methodName,
- String methodSignature) throws ClassNotFoundException {
- ClassNode classNode = mutableClass.classNode;
- while (true) {
- List<MethodNode> methods = new ArrayList<>(classNode.methods);
-
- for (MethodNode method : methods) {
- if (method.name.equals(methodName) && method.desc.equals(methodSignature)) {
- if ((method.access & Opcodes.ACC_FINAL) != 0) {
- return true;
- }
- }
- }
-
- if (classNode.superName == null) {
- return false;
- }
-
- classNode = mutableClass.classNodeProvider.getClassNode(classNode.superName);
- }
- }
-
private boolean isSyntheticAccessorMethod(MethodNode method) {
return (method.access & Opcodes.ACC_SYNTHETIC) != 0;
}
diff --git a/sandbox/src/main/java/org/robolectric/internal/bytecode/InvocationProfile.java b/sandbox/src/main/java/org/robolectric/internal/bytecode/InvocationProfile.java
index 7ea34a7d6..6766f8674 100644
--- a/sandbox/src/main/java/org/robolectric/internal/bytecode/InvocationProfile.java
+++ b/sandbox/src/main/java/org/robolectric/internal/bytecode/InvocationProfile.java
@@ -43,7 +43,7 @@ public class InvocationProfile {
}
boolean isAndroidSupport() {
- return clazz.getName().startsWith("android.support");
+ return clazz.getName().startsWith("android.support") || clazz.getName().startsWith("androidx.");
}
boolean strict() {
@@ -53,7 +53,9 @@ public class InvocationProfile {
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ if (!(o instanceof InvocationProfile)) {
+ return false;
+ }
InvocationProfile that = (InvocationProfile) o;
diff --git a/sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowMap.java b/sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowMap.java
index 8d7d9836a..189131abb 100644
--- a/sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowMap.java
+++ b/sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowMap.java
@@ -2,13 +2,11 @@ package org.robolectric.internal.bytecode;
import com.google.common.collect.ImmutableMap;
import java.lang.reflect.InvocationTargetException;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implements;
import org.robolectric.internal.ShadowProvider;
import org.robolectric.shadow.api.ShadowPicker;
@@ -35,8 +33,8 @@ public class ShadowMap {
final Map<String, String> shadowMap = new HashMap<>();
final Map<String, String> shadowPickerMap = new HashMap<>();
for (ShadowProvider provider : shadowProviders) {
- shadowMap.putAll(provider.getShadowMap());
- shadowPickerMap.putAll(provider.getShadowPickerMap());
+ shadowMap.putAll(provider.getShadowMap());
+ shadowPickerMap.putAll(provider.getShadowPickerMap());
}
return new ShadowMap(ImmutableMap.copyOf(shadowMap), Collections.emptyMap(),
ImmutableMap.copyOf(shadowPickerMap));
@@ -117,14 +115,6 @@ public class ShadowMap {
}
}
- /**
- * @deprecated use {@link #obtainShadowInfo(Class)} instead
- */
- @Deprecated
- public static ShadowInfo getShadowInfo(Class<?> shadowClass) {
- return obtainShadowInfo(shadowClass);
- }
-
public static ShadowInfo obtainShadowInfo(Class<?> clazz) {
return obtainShadowInfo(clazz, false);
}
@@ -224,48 +214,12 @@ public class ShadowMap {
return this;
}
- /** @deprecated Use the Robolectric annotation processor or {@link Config#shadows()} instead. */
- @Deprecated
- public Builder addShadowClasses(Collection<Class<?>> shadowClasses) {
- for (Class<?> shadowClass : shadowClasses) {
- addShadowClass(shadowClass);
- }
- return this;
- }
-
- /** @deprecated Use the Robolectric annotation processor or {@link Config#shadows()} instead. */
- @Deprecated
- public Builder addShadowClass(Class<?> shadowClass) {
+ Builder addShadowClass(Class<?> shadowClass) {
addShadowInfo(obtainShadowInfo(shadowClass));
return this;
}
- /** @deprecated Use the Robolectric annotation processor or {@link Config#shadows()} instead. */
- @Deprecated
- public Builder addShadowClass(
- String realClassName,
- Class<?> shadowClass,
- boolean callThroughByDefault,
- boolean looseSignatures) {
- addShadowClass(realClassName, shadowClass.getName(), callThroughByDefault, looseSignatures);
- return this;
- }
-
- /** @deprecated Use the Robolectric annotation processor or {@link Config#shadows()} instead. */
- @Deprecated
- public Builder addShadowClass(
- Class<?> realClass,
- Class<?> shadowClass,
- boolean callThroughByDefault,
- boolean looseSignatures) {
- addShadowClass(
- realClass.getName(), shadowClass.getName(), callThroughByDefault, looseSignatures);
- return this;
- }
-
- /** @deprecated Use the Robolectric annotation processor or {@link Config#shadows()} instead. */
- @Deprecated
- public Builder addShadowClass(
+ Builder addShadowClass(
String realClassName,
String shadowClassName,
boolean callThroughByDefault,
diff --git a/sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowWrangler.java b/sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowWrangler.java
index 4de178aa9..5c10ef2d3 100644
--- a/sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowWrangler.java
+++ b/sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowWrangler.java
@@ -209,6 +209,7 @@ public class ShadowWrangler implements ClassHandler {
return DO_NOTHING;
}
+ shadowMethod.setAccessible(true);
MethodHandle mh = LOOKUP.unreflect(shadowMethod);
// Robolectric doesn't actually look for static, this for example happens
diff --git a/scripts/build-resources.rb b/scripts/build-resources.rb
deleted file mode 100755
index 3ef1008f3..000000000
--- a/scripts/build-resources.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env ruby
-#
-# This script can be used to regenerate sequential resource ids when the
-# R.java file is modified in the src/test/resources/res folder.
-#
-# Note: this script does *NOT* generate resource ids that are consistent
-# with the Android aapt tool. This script will likely be removed at some
-# near point in the future and replaced by something that invokes aapt
-# directly.
-
-GIT_ROOT = `git rev-parse --show-toplevel`.chomp
-START = 0x7f000000
-INCR = 0x10000
-
-path_to_r = File.join(GIT_ROOT, "robolectric/src/test/java/org/robolectric/R.java")
-if path_to_r =~ /^\/path\/to/
- raise "please change the path to this file!"
-else
- original_contents = File.read(path_to_r)
- num_classes = 0
- x = START
- new_contents = original_contents.gsub(/class|0x[0-9a-fA-F]+;/) do |match|
- if match == "class"
- x = START + INCR * num_classes
- num_classes += 1
- "class"
- else
- val = "0x#{"%x"%x};"
- x += 1
- val
- end
- end
- File.open(path_to_r, "w") { |f| f << new_contents }
-end
diff --git a/scripts/build-resources.sh b/scripts/build-resources.sh
index dccc62a95..dad138087 100755
--- a/scripts/build-resources.sh
+++ b/scripts/build-resources.sh
@@ -6,7 +6,8 @@ scriptsDir=`dirname $0`
androidProjDir=`dirname $scriptsDir`/robolectric
echo $androidProjDir
-aapt=$ANDROID_HOME/build-tools/28.0.1/aapt
+aapts=( $ANDROID_HOME/build-tools/28.0.*/aapt )
+aapt=${aapts[-1]}
inDir=$androidProjDir/src/test/resources
outDir=$androidProjDir/src/test/resources
javaSrc=$androidProjDir/src/test/java
diff --git a/scripts/install-dependencies.rb b/scripts/install-dependencies.rb
index 21d1f2f01..8d64bf736 100755
--- a/scripts/install-dependencies.rb
+++ b/scripts/install-dependencies.rb
@@ -18,23 +18,23 @@ def concat_maven_file_segments(repo_root_dir, group_id, artifact_id, version, ex
raise ArgumentError, "Group ID, Artifact ID, Version, and/or Extension arguments are invalid. Please check your inputs."
end
# Generate dependency path segments
- dep_path_segments = []
+ dep_path_segments = []
artifact_file_name = "#{artifact_id}-#{version}.#{extension}"
# Start with the root repo dir
dep_path_segments << repo_root_dir
# Add the split group id segments into the path segments
dep_path_segments << group_id.split(".")
-
+
# Then add the artifact id
dep_path_segments << artifact_id
-
+
# Then add the version ID
dep_path_segments << version
-
+
# Finally, add the version file
dep_path_segments << artifact_file_name
-
+
# Concatenate the segments into the target archive
dep_path_segments.join("/")
end
@@ -144,8 +144,10 @@ MULTIDEX_VERSION = "1.0.1"
ANDROIDX_TEST_GROUP_ID = "androidx.test"
MONITOR_ARTIFACT_ID = "monitor"
CORE_ARTIFACT_ID = "core"
-ANDROIDX_TEST_VERSION = "1.1.0-alpha4"
-ANDROIDX_TEST_CORE_VERSION = "1.0.0-alpha4"
+ANDROIDX_TEST_EXT_GROUP_ID = "androidx.test.ext"
+EXT_JUNIT_ARTIFACT_ID = "junit"
+ANDROIDX_TEST_VERSION = "1.1.0"
+ANDROIDX_TEST_CORE_VERSION = "1.0.0"
# Play Services constants
PLAY_SERVICES_GROUP_ID = "com.google.android.gms"
@@ -201,3 +203,4 @@ install_supportlib_from_gmaven('support-media-compat')
install_from_gmaven(ANDROIDX_TEST_GROUP_ID, MONITOR_ARTIFACT_ID, ANDROIDX_TEST_VERSION)
install_from_gmaven(ANDROIDX_TEST_GROUP_ID, CORE_ARTIFACT_ID, ANDROIDX_TEST_CORE_VERSION)
+install_from_gmaven(ANDROIDX_TEST_EXT_GROUP_ID, EXT_JUNIT_ARTIFACT_ID, ANDROIDX_TEST_CORE_VERSION)
diff --git a/scripts/update-cpp.sh b/scripts/update-cpp.sh
index 122c56058..216815b4a 100755
--- a/scripts/update-cpp.sh
+++ b/scripts/update-cpp.sh
@@ -4,7 +4,7 @@ set -e
#currentVersion=android-8.0.0_r36
#currentVersion=android-8.1.0_r22
-currentVersion=android-9.0.0_r3
+currentVersion=android-9.0.0_r12
baseDir=`dirname $0`/..
frameworksBaseRepoDir="$HOME/Dev/AOSP/frameworks/base"
@@ -32,12 +32,18 @@ function showDiffs2() {
fi
if [ "x$curSha" != "x$thisSha" ]; then
- tmpFile="/tmp/diff.tmp"
- rm -f "$tmpFile"
- echo "Apply changes to: $file" > "$tmpFile"
- echo " From $repoFile $version -> $currentVersion" >> "$tmpFile"
- (cd "$frameworksBaseRepoDir" && git diff --color=always "${version}..${currentVersion}" "--" "$repoFile" >> "$tmpFile")
- less -r "$tmpFile"
+ (cd "$frameworksBaseRepoDir" && git diff --quiet "${version}..${currentVersion}" "--" "$repoFile")
+ if [ $? -eq 0 ]; then
+ echo "No changes in: $file"
+ echo " From $repoFile $version -> $currentVersion"
+ else
+ tmpFile="/tmp/diff.tmp"
+ rm -f "$tmpFile"
+ echo "Apply changes to: $file" > "$tmpFile"
+ echo " From $repoFile $version -> $currentVersion" >> "$tmpFile"
+ (cd "$frameworksBaseRepoDir" && git diff --color=always "${version}..${currentVersion}" "--" "$repoFile" >> "$tmpFile")
+ less -r "$tmpFile"
+ fi
fi
}
diff --git a/shadowapi/build.gradle b/shadowapi/build.gradle
index 7d9add699..794c15e65 100644
--- a/shadowapi/build.gradle
+++ b/shadowapi/build.gradle
@@ -1,17 +1,11 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
dependencies {
- // Compile dependencies
- compileOnly "com.google.code.findbugs:jsr305:3.0.1"
+ compileOnly "com.google.code.findbugs:jsr305:3.0.2"
- // Testing dependencies
- testCompile "junit:junit:4.12"
- testCompile "com.google.truth:truth:0.39"
- testCompile "org.mockito:mockito-core:2.5.4"
+ testImplementation "junit:junit:4.12"
+ testImplementation "com.google.truth:truth:0.42"
+ testImplementation "org.mockito:mockito-core:2.5.4"
} \ No newline at end of file
diff --git a/shadows/androidx/fragment/Android.mk b/shadows/androidx/fragment/Android.mk
index 6f07f5b94..abb656795 100644
--- a/shadows/androidx/fragment/Android.mk
+++ b/shadows/androidx/fragment/Android.mk
@@ -35,7 +35,7 @@ LOCAL_MODULE := Robolectric_shadows_androidx_fragment_tests
LOCAL_SRC_FILES := $(call all-java-files-under, src/test/java)
-LOCAL_JAVA_RESOURCE_DIRS := src/test/resources
+LOCAL_JAVA_RESOURCE_DIRS := src/test/resources/res
LOCAL_JAVA_LIBRARIES := \
Robolectric_shadows_androidx_fragment \
diff --git a/shadows/androidx/fragment/src/test/java/org/robolectric/shadows/androidx/fragment/FragmentControllerTest.java b/shadows/androidx/fragment/src/test/java/org/robolectric/shadows/androidx/fragment/FragmentControllerTest.java
index 89808ea4a..77373ca85 100644
--- a/shadows/androidx/fragment/src/test/java/org/robolectric/shadows/androidx/fragment/FragmentControllerTest.java
+++ b/shadows/androidx/fragment/src/test/java/org/robolectric/shadows/androidx/fragment/FragmentControllerTest.java
@@ -16,10 +16,10 @@ import java.util.List;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.robolectric.util.TestRunnerWithManifest;
+import org.robolectric.RobolectricTestRunner;
/** Tests for {@link FragmentController} */
-@RunWith(TestRunnerWithManifest.class)
+@RunWith(RobolectricTestRunner.class)
public class FragmentControllerTest {
@After
@@ -232,7 +232,7 @@ public class FragmentControllerTest {
@Test
public void
- setupFragmentWithFragmentAndActivityAndContainViewIdAndBundle_fragmentHasCorrectLifecycle() {
+ setupFragmentWithFragmentAndActivityAndContainViewIdAndBundle_fragmentHasCorrectLifecycle() {
Bundle testBundle = generateTestBundle();
TranscriptFragment fragment =
FragmentController.setupFragment(
diff --git a/shadows/androidx/fragment/src/test/java/org/robolectric/util/TestRunnerWithManifest.java b/shadows/androidx/fragment/src/test/java/org/robolectric/util/TestRunnerWithManifest.java
deleted file mode 100644
index 4a6349734..000000000
--- a/shadows/androidx/fragment/src/test/java/org/robolectric/util/TestRunnerWithManifest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.robolectric.util;
-
-import org.junit.runners.model.InitializationError;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
-import org.robolectric.manifest.AndroidManifest;
-import org.robolectric.res.Fs;
-import org.robolectric.res.FsFile;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URL;
-
-public class TestRunnerWithManifest extends RobolectricTestRunner {
- public TestRunnerWithManifest(Class<?> testClass) throws InitializationError {
- super(testClass);
- }
-
- private static FsFile resourceFile(String... pathParts) {
- return Fs.newFile(resourcesBaseDirFile()).join(pathParts);
- }
-
- private static File resourcesBaseDirFile() {
- // Try to locate the manifest file as a classpath resource.
- final String resourceName = "/src/test/resources/AndroidManifest.xml";
- final URL resourceUrl = TestRunnerWithManifest.class.getResource(resourceName);
- if (resourceUrl != null && "file".equals(resourceUrl.getProtocol())) {
- // Construct a path to the manifest file relative to the current working directory.
- final URI workingDirectory = URI.create(System.getProperty("user.dir"));
- final URI absolutePath = URI.create(resourceUrl.getPath());
- final URI relativePath = workingDirectory.relativize(absolutePath);
- return new File(relativePath.toString()).getParentFile();
- }
-
- // Return a path relative to the current working directory.
- return Util.file("src", "test", "resources");
- }
-
- @Override
- protected AndroidManifest getAppManifest(Config config) {
- return new AndroidManifest(resourceFile("AndroidManifest.xml"), resourceFile("res"),
- resourceFile("assets"));
- }
-}
diff --git a/shadows/framework/build.gradle b/shadows/framework/build.gradle
index 65b6a9319..3dc523cab 100644
--- a/shadows/framework/build.gradle
+++ b/shadows/framework/build.gradle
@@ -1,7 +1,3 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
@@ -41,17 +37,15 @@ jar {
}
dependencies {
- // Project dependencies
- compile project(":annotations")
- compile project(":resources")
- compile project(":utils")
-
- // Compile dependencies
- compileOnly "com.google.code.findbugs:jsr305:3.0.1"
- compile "com.almworks.sqlite4java:sqlite4java:0.282"
+ api project(":annotations")
+ api project(":resources")
+ api project(":utils")
+
+ compileOnly "com.google.code.findbugs:jsr305:3.0.2"
+ api "com.almworks.sqlite4java:sqlite4java:0.282"
compileOnly(AndroidSdk.MAX_SDK.coordinates) { force = true }
- compile "com.ibm.icu:icu4j:53.1"
- compile "com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.1"
+ api "com.ibm.icu:icu4j:53.1"
+ api "com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.1"
jni "com.github.axet.litedb:libsqlite:0.282-3:natives-mac-x86_64"
jni "com.github.axet.litedb:libsqlite:0.282-3:natives-linux-x86"
diff --git a/shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java b/shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java
index 019bbf0ab..48a72b3e6 100644
--- a/shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java
+++ b/shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java
@@ -17,7 +17,12 @@ import org.robolectric.util.TempDirectory;
public class RuntimeEnvironment {
public static Context systemContext;
- public static Application application;
+
+ /**
+ * @deprecated Please migrate to {@link
+ * androidx.test.core.app.ApplicationProvider#getApplicationContext}
+ */
+ @Deprecated public static Application application;
private volatile static Thread mainThread = Thread.currentThread();
private static Object activityThread;
diff --git a/shadows/framework/src/main/java/org/robolectric/android/ConfigurationV25.java b/shadows/framework/src/main/java/org/robolectric/android/ConfigurationV25.java
index ba880a675..d92298a8e 100644
--- a/shadows/framework/src/main/java/org/robolectric/android/ConfigurationV25.java
+++ b/shadows/framework/src/main/java/org/robolectric/android/ConfigurationV25.java
@@ -15,7 +15,7 @@ import java.util.List;
import java.util.Locale;
import org.robolectric.RuntimeEnvironment;
-// adapted from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/core/java/android/content/res/Configuration.java
+// adapted from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/core/java/android/content/res/Configuration.java
public class ConfigurationV25 {
private static String localesToResourceQualifier(List<Locale> locs) {
diff --git a/shadows/framework/src/main/java/org/robolectric/android/controller/ActivityController.java b/shadows/framework/src/main/java/org/robolectric/android/controller/ActivityController.java
index f879ef6a7..8a0af2b11 100644
--- a/shadows/framework/src/main/java/org/robolectric/android/controller/ActivityController.java
+++ b/shadows/framework/src/main/java/org/robolectric/android/controller/ActivityController.java
@@ -6,7 +6,9 @@ import static org.robolectric.shadow.api.Shadow.extract;
import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
import android.app.Activity;
+import android.app.ActivityThread;
import android.app.Application;
+import android.app.Instrumentation;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -55,12 +57,7 @@ public class ActivityController<T extends Activity> extends ComponentController<
}
public ActivityController<T> create(final Bundle bundle) {
- shadowMainLooper.runPaused(new Runnable() {
- @Override
- public void run() {
- ReflectionHelpers.callInstanceMethod(Activity.class, component, "performCreate", from(Bundle.class, bundle));
- }
- });
+ shadowMainLooper.runPaused(() -> getInstrumentation().callActivityOnCreate(component, bundle));
return this;
}
@@ -80,7 +77,9 @@ public class ActivityController<T extends Activity> extends ComponentController<
}
public ActivityController<T> start() {
-
+ // Start and stop are tricky cases. Unlike other lifecycle methods such as
+ // Instrumentation#callActivityOnPause calls Activity#performPause, Activity#performStop calls
+ // Instrumentation#callActivityOnStop internally so the dependency direction is the opposite.
if (RuntimeEnvironment.getApiLevel() <= O_MR1) {
invokeWhilePaused("performStart");
} else {
@@ -90,7 +89,8 @@ public class ActivityController<T extends Activity> extends ComponentController<
}
public ActivityController<T> restoreInstanceState(Bundle bundle) {
- invokeWhilePaused("performRestoreInstanceState", from(Bundle.class, bundle));
+ shadowMainLooper.runPaused(
+ () -> getInstrumentation().callActivityOnRestoreInstanceState(component, bundle));
return this;
}
@@ -144,21 +144,25 @@ public class ActivityController<T extends Activity> extends ComponentController<
}
public ActivityController<T> userLeaving() {
- invokeWhilePaused("performUserLeaving");
+ shadowMainLooper.runPaused(() -> getInstrumentation().callActivityOnUserLeaving(component));
return this;
}
public ActivityController<T> pause() {
- invokeWhilePaused("performPause");
+ shadowMainLooper.runPaused(() -> getInstrumentation().callActivityOnPause(component));
return this;
}
public ActivityController<T> saveInstanceState(Bundle outState) {
- invokeWhilePaused("performSaveInstanceState", from(Bundle.class, outState));
+ shadowMainLooper.runPaused(
+ () -> getInstrumentation().callActivityOnSaveInstanceState(component, outState));
return this;
}
public ActivityController<T> stop() {
+ // Stop and start are tricky cases. Unlike other lifecycle methods such as
+ // Instrumentation#callActivityOnPause calls Activity#performPause, Activity#performStop calls
+ // Instrumentation#callActivityOnStop internally so the dependency direction is the opposite.
if (RuntimeEnvironment.getApiLevel() <= M) {
invokeWhilePaused("performStop");
} else if (RuntimeEnvironment.getApiLevel() <= O_MR1) {
@@ -170,7 +174,7 @@ public class ActivityController<T extends Activity> extends ComponentController<
}
@Override public ActivityController<T> destroy() {
- invokeWhilePaused("performDestroy");
+ shadowMainLooper.runPaused(() -> getInstrumentation().callActivityOnDestroy(component));
return this;
}
@@ -364,4 +368,8 @@ public class ActivityController<T extends Activity> extends ComponentController<
return this;
}
+
+ private static Instrumentation getInstrumentation() {
+ return ((ActivityThread) RuntimeEnvironment.getActivityThread()).getInstrumentation();
+ }
}
diff --git a/shadows/framework/src/main/java/org/robolectric/fakes/RoboCursor.java b/shadows/framework/src/main/java/org/robolectric/fakes/RoboCursor.java
index 765e36bae..c419383c1 100644
--- a/shadows/framework/src/main/java/org/robolectric/fakes/RoboCursor.java
+++ b/shadows/framework/src/main/java/org/robolectric/fakes/RoboCursor.java
@@ -64,7 +64,12 @@ public class RoboCursor extends BaseCursor {
@Override
public long getLong(int columnIndex) {
- return (Long) results[resultsIndex][columnIndex];
+ Object value = results[resultsIndex][columnIndex];
+ return value == null
+ ? 0
+ : (value instanceof Number
+ ? ((Number) value).longValue()
+ : Long.parseLong(value.toString()));
}
@Override
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/CachedPathIteratorFactory.java b/shadows/framework/src/main/java/org/robolectric/shadows/CachedPathIteratorFactory.java
new file mode 100644
index 000000000..3ad4d8b39
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/CachedPathIteratorFactory.java
@@ -0,0 +1,469 @@
+package org.robolectric.shadows;
+
+import java.awt.geom.CubicCurve2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.QuadCurve2D;
+import java.util.ArrayList;
+
+/**
+ * Class that returns iterators for a given path. These iterators are lightweight and can be reused
+ * multiple times to iterate over the path.
+ *
+ * <p>copied from
+ * https://github.com/aosp-mirror/platform_frameworks_base/blob/oreo-release/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/util/CachedPathIteratorFactory.java
+ */
+public class CachedPathIteratorFactory {
+ /*
+ * A few conventions used in the code:
+ * Coordinates or coords arrays store segment coordinates. They use the same format as
+ * PathIterator#currentSegment coordinates array.
+ * float arrays store always points where the first element is X and the second is Y.
+ */
+
+ // This governs how accurate the approximation of the Path is.
+ private static final float PRECISION = 0.002f;
+
+ private final int mWindingRule;
+ private final int[] mTypes;
+ private final float[][] mCoordinates;
+ private final float[] mSegmentsLength;
+ private final float mTotalLength;
+
+ public CachedPathIteratorFactory(PathIterator iterator) {
+ mWindingRule = iterator.getWindingRule();
+
+ ArrayList<Integer> typesArray = new ArrayList<>();
+ ArrayList<float[]> pointsArray = new ArrayList<>();
+ float[] points = new float[6];
+ while (!iterator.isDone()) {
+ int type = iterator.currentSegment(points);
+ int nPoints = getNumberOfPoints(type) * 2; // 2 coordinates per point
+
+ typesArray.add(type);
+ float[] itemPoints = new float[nPoints];
+ System.arraycopy(points, 0, itemPoints, 0, nPoints);
+ pointsArray.add(itemPoints);
+ iterator.next();
+ }
+
+ mTypes = new int[typesArray.size()];
+ mCoordinates = new float[mTypes.length][];
+ for (int i = 0; i < typesArray.size(); i++) {
+ mTypes[i] = typesArray.get(i);
+ mCoordinates[i] = pointsArray.get(i);
+ }
+
+ // Do measurement
+ mSegmentsLength = new float[mTypes.length];
+
+ // Curves that we can reuse to estimate segments length
+ CubicCurve2D.Float cubicCurve = new CubicCurve2D.Float();
+ QuadCurve2D.Float quadCurve = new QuadCurve2D.Float();
+ float lastX = 0;
+ float lastY = 0;
+ float totalLength = 0;
+ for (int i = 0; i < mTypes.length; i++) {
+ switch (mTypes[i]) {
+ case PathIterator.SEG_CUBICTO:
+ cubicCurve.setCurve(
+ lastX,
+ lastY,
+ mCoordinates[i][0],
+ mCoordinates[i][1],
+ mCoordinates[i][2],
+ mCoordinates[i][3],
+ lastX = mCoordinates[i][4],
+ lastY = mCoordinates[i][5]);
+ mSegmentsLength[i] = getFlatPathLength(cubicCurve.getPathIterator(null, PRECISION));
+ break;
+ case PathIterator.SEG_QUADTO:
+ quadCurve.setCurve(
+ lastX,
+ lastY,
+ mCoordinates[i][0],
+ mCoordinates[i][1],
+ lastX = mCoordinates[i][2],
+ lastY = mCoordinates[i][3]);
+ mSegmentsLength[i] = getFlatPathLength(quadCurve.getPathIterator(null, PRECISION));
+ break;
+ case PathIterator.SEG_CLOSE:
+ mSegmentsLength[i] =
+ (float)
+ Point2D.distance(
+ lastX, lastY, lastX = mCoordinates[0][0], lastY = mCoordinates[0][1]);
+ mCoordinates[i] = new float[2];
+ // We convert a SEG_CLOSE segment to a SEG_LINETO so we do not have to worry
+ // about this special case in the rest of the code.
+ mTypes[i] = PathIterator.SEG_LINETO;
+ mCoordinates[i][0] = mCoordinates[0][0];
+ mCoordinates[i][1] = mCoordinates[0][1];
+ break;
+ case PathIterator.SEG_MOVETO:
+ mSegmentsLength[i] = 0;
+ lastX = mCoordinates[i][0];
+ lastY = mCoordinates[i][1];
+ break;
+ case PathIterator.SEG_LINETO:
+ mSegmentsLength[i] =
+ (float) Point2D.distance(lastX, lastY, mCoordinates[i][0], mCoordinates[i][1]);
+ lastX = mCoordinates[i][0];
+ lastY = mCoordinates[i][1];
+ break;
+ default:
+ }
+ totalLength += mSegmentsLength[i];
+ }
+
+ mTotalLength = totalLength;
+ }
+
+ private static void quadCurveSegment(float[] coords, float t0, float t1) {
+ // Calculate X and Y at 0.5 (We'll use this to reconstruct the control point later)
+ float mt = t0 + (t1 - t0) / 2;
+ float mu = 1 - mt;
+ float mx = mu * mu * coords[0] + 2 * mu * mt * coords[2] + mt * mt * coords[4];
+ float my = mu * mu * coords[1] + 2 * mu * mt * coords[3] + mt * mt * coords[5];
+
+ float u0 = 1 - t0;
+ float u1 = 1 - t1;
+
+ // coords at t0
+ coords[0] = coords[0] * u0 * u0 + coords[2] * 2 * t0 * u0 + coords[4] * t0 * t0;
+ coords[1] = coords[1] * u0 * u0 + coords[3] * 2 * t0 * u0 + coords[5] * t0 * t0;
+
+ // coords at t1
+ coords[4] = coords[0] * u1 * u1 + coords[2] * 2 * t1 * u1 + coords[4] * t1 * t1;
+ coords[5] = coords[1] * u1 * u1 + coords[3] * 2 * t1 * u1 + coords[5] * t1 * t1;
+
+ // estimated control point at t'=0.5
+ coords[2] = 2 * mx - coords[0] / 2 - coords[4] / 2;
+ coords[3] = 2 * my - coords[1] / 2 - coords[5] / 2;
+ }
+
+ private static void cubicCurveSegment(float[] coords, float t0, float t1) {
+ // http://stackoverflow.com/questions/11703283/cubic-bezier-curve-segment
+ float u0 = 1 - t0;
+ float u1 = 1 - t1;
+
+ // Calculate the points at t0 and t1 for the quadratic curves formed by (P0, P1, P2) and
+ // (P1, P2, P3)
+ float qxa = coords[0] * u0 * u0 + coords[2] * 2 * t0 * u0 + coords[4] * t0 * t0;
+ float qxb = coords[0] * u1 * u1 + coords[2] * 2 * t1 * u1 + coords[4] * t1 * t1;
+ float qxc = coords[2] * u0 * u0 + coords[4] * 2 * t0 * u0 + coords[6] * t0 * t0;
+ float qxd = coords[2] * u1 * u1 + coords[4] * 2 * t1 * u1 + coords[6] * t1 * t1;
+
+ float qya = coords[1] * u0 * u0 + coords[3] * 2 * t0 * u0 + coords[5] * t0 * t0;
+ float qyb = coords[1] * u1 * u1 + coords[3] * 2 * t1 * u1 + coords[5] * t1 * t1;
+ float qyc = coords[3] * u0 * u0 + coords[5] * 2 * t0 * u0 + coords[7] * t0 * t0;
+ float qyd = coords[3] * u1 * u1 + coords[5] * 2 * t1 * u1 + coords[7] * t1 * t1;
+
+ // Linear interpolation
+ coords[0] = qxa * u0 + qxc * t0;
+ coords[1] = qya * u0 + qyc * t0;
+
+ coords[2] = qxa * u1 + qxc * t1;
+ coords[3] = qya * u1 + qyc * t1;
+
+ coords[4] = qxb * u0 + qxd * t0;
+ coords[5] = qyb * u0 + qyd * t0;
+
+ coords[6] = qxb * u1 + qxd * t1;
+ coords[7] = qyb * u1 + qyd * t1;
+ }
+
+ /**
+ * Returns the end point of a given segment
+ *
+ * @param type the segment type
+ * @param coords the segment coordinates array
+ * @param point the return array where the point will be stored
+ */
+ private static void getShapeEndPoint(int type, float[] coords, float[] point) {
+ // start index of the end point for the segment type
+ int pointIndex = (getNumberOfPoints(type) - 1) * 2;
+ point[0] = coords[pointIndex];
+ point[1] = coords[pointIndex + 1];
+ }
+
+ /** Returns the number of points stored in a coordinates array for the given segment type. */
+ private static int getNumberOfPoints(int segmentType) {
+ switch (segmentType) {
+ case PathIterator.SEG_QUADTO:
+ return 2;
+ case PathIterator.SEG_CUBICTO:
+ return 3;
+ case PathIterator.SEG_CLOSE:
+ return 0;
+ default:
+ return 1;
+ }
+ }
+
+ /**
+ * Returns the estimated length of a flat path. If the passed path is not flat (i.e. contains a
+ * segment that is not {@link PathIterator#SEG_CLOSE}, {@link PathIterator#SEG_MOVETO} or {@link
+ * PathIterator#SEG_LINETO} this method will fail.
+ */
+ private static float getFlatPathLength(PathIterator iterator) {
+ float segment[] = new float[6];
+ float totalLength = 0;
+ float[] previousPoint = new float[2];
+ boolean isFirstPoint = true;
+
+ while (!iterator.isDone()) {
+ int type = iterator.currentSegment(segment);
+ assert type == PathIterator.SEG_LINETO
+ || type == PathIterator.SEG_CLOSE
+ || type == PathIterator.SEG_MOVETO;
+
+ // MoveTo shouldn't affect the length
+ if (!isFirstPoint && type != PathIterator.SEG_MOVETO) {
+ totalLength += Point2D.distance(previousPoint[0], previousPoint[1], segment[0], segment[1]);
+ } else {
+ isFirstPoint = false;
+ }
+ previousPoint[0] = segment[0];
+ previousPoint[1] = segment[1];
+ iterator.next();
+ }
+
+ return totalLength;
+ }
+
+ /** Returns the estimated position along a path of the given length. */
+ private void getPointAtLength(
+ int type, float[] coords, float lastX, float lastY, float t, float[] point) {
+ if (type == PathIterator.SEG_LINETO) {
+ point[0] = lastX + (coords[0] - lastX) * t;
+ point[1] = lastY + (coords[1] - lastY) * t;
+ // Return here, since we do not need a shape to estimate
+ return;
+ }
+
+ float[] curve = new float[8];
+ int lastPointIndex = (getNumberOfPoints(type) - 1) * 2;
+
+ System.arraycopy(coords, 0, curve, 2, coords.length);
+ curve[0] = lastX;
+ curve[1] = lastY;
+ if (type == PathIterator.SEG_CUBICTO) {
+ cubicCurveSegment(curve, 0f, t);
+ } else {
+ quadCurveSegment(curve, 0f, t);
+ }
+
+ point[0] = curve[2 + lastPointIndex];
+ point[1] = curve[2 + lastPointIndex + 1];
+ }
+
+ public CachedPathIterator iterator() {
+ return new CachedPathIterator();
+ }
+
+ /** Class that allows us to iterate over a path multiple times */
+ public class CachedPathIterator implements PathIterator {
+ private int mNextIndex;
+
+ /**
+ * Current segment type.
+ *
+ * @see PathIterator
+ */
+ private int mCurrentType;
+
+ /**
+ * Stores the coordinates array of the current segment. The number of points stored depends on
+ * the segment type.
+ *
+ * @see PathIterator
+ */
+ private float[] mCurrentCoords = new float[6];
+
+ private float mCurrentSegmentLength;
+
+ /**
+ * Current segment length offset. When asking for the length of the current segment, the length
+ * will be reduced by this amount. This is useful when we are only using portions of the
+ * segment.
+ *
+ * @see #jumpToSegment(float)
+ */
+ private float mOffsetLength;
+
+ /** Point where the current segment started */
+ private float[] mLastPoint = new float[2];
+
+ private boolean isIteratorDone;
+
+ private CachedPathIterator() {
+ next();
+ }
+
+ public float getCurrentSegmentLength() {
+ return mCurrentSegmentLength;
+ }
+
+ @Override
+ public int getWindingRule() {
+ return mWindingRule;
+ }
+
+ @Override
+ public boolean isDone() {
+ return isIteratorDone;
+ }
+
+ @Override
+ public void next() {
+ if (mNextIndex >= mTypes.length) {
+ isIteratorDone = true;
+ return;
+ }
+
+ if (mNextIndex >= 1) {
+ // We've already called next() once so there is a previous segment in this path.
+ // We want to get the coordinates where the path ends.
+ getShapeEndPoint(mCurrentType, mCurrentCoords, mLastPoint);
+ } else {
+ // This is the first segment, no previous point so initialize to 0, 0
+ mLastPoint[0] = mLastPoint[1] = 0f;
+ }
+ mCurrentType = mTypes[mNextIndex];
+ mCurrentSegmentLength = mSegmentsLength[mNextIndex] - mOffsetLength;
+
+ if (mOffsetLength > 0f && (mCurrentType == SEG_CUBICTO || mCurrentType == SEG_QUADTO)) {
+ // We need to skip part of the start of the current segment (because
+ // mOffsetLength > 0)
+ float[] points = new float[8];
+
+ if (mNextIndex < 1) {
+ points[0] = points[1] = 0f;
+ } else {
+ getShapeEndPoint(mTypes[mNextIndex - 1], mCoordinates[mNextIndex - 1], points);
+ }
+
+ System.arraycopy(mCoordinates[mNextIndex], 0, points, 2, mCoordinates[mNextIndex].length);
+ float t0 =
+ (mSegmentsLength[mNextIndex] - mCurrentSegmentLength) / mSegmentsLength[mNextIndex];
+ if (mCurrentType == SEG_CUBICTO) {
+ cubicCurveSegment(points, t0, 1f);
+ } else {
+ quadCurveSegment(points, t0, 1f);
+ }
+ System.arraycopy(points, 2, mCurrentCoords, 0, mCoordinates[mNextIndex].length);
+ } else {
+ System.arraycopy(
+ mCoordinates[mNextIndex], 0, mCurrentCoords, 0, mCoordinates[mNextIndex].length);
+ }
+
+ mOffsetLength = 0f;
+ mNextIndex++;
+ }
+
+ @Override
+ public int currentSegment(float[] coords) {
+ System.arraycopy(mCurrentCoords, 0, coords, 0, getNumberOfPoints(mCurrentType) * 2);
+ return mCurrentType;
+ }
+
+ @Override
+ public int currentSegment(double[] coords) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** Returns the point where the current segment ends */
+ public void getCurrentSegmentEnd(float[] point) {
+ point[0] = mLastPoint[0];
+ point[1] = mLastPoint[1];
+ }
+
+ /** Restarts the iterator and jumps all the segments of this path up to the length value. */
+ public void jumpToSegment(float length) {
+ isIteratorDone = false;
+ if (length <= 0f) {
+ mNextIndex = 0;
+ return;
+ }
+
+ float accLength = 0;
+ float lastPoint[] = new float[2];
+ for (mNextIndex = 0; mNextIndex < mTypes.length; mNextIndex++) {
+ float segmentLength = mSegmentsLength[mNextIndex];
+ if (accLength + segmentLength >= length && mTypes[mNextIndex] != SEG_MOVETO) {
+ float[] estimatedPoint = new float[2];
+ getPointAtLength(
+ mTypes[mNextIndex],
+ mCoordinates[mNextIndex],
+ lastPoint[0],
+ lastPoint[1],
+ (length - accLength) / segmentLength,
+ estimatedPoint);
+
+ // This segment makes us go further than length so we go back one step,
+ // set a moveto and offset the length of the next segment by the length
+ // of this segment that we've already used.
+ mCurrentType = PathIterator.SEG_MOVETO;
+ mCurrentCoords[0] = estimatedPoint[0];
+ mCurrentCoords[1] = estimatedPoint[1];
+ mCurrentSegmentLength = 0;
+
+ // We need to offset next path length to account for the segment we've just
+ // skipped.
+ mOffsetLength = length - accLength;
+ return;
+ }
+ accLength += segmentLength;
+ getShapeEndPoint(mTypes[mNextIndex], mCoordinates[mNextIndex], lastPoint);
+ }
+ }
+
+ /**
+ * Returns the current segment up to certain length. If the current segment is shorter than
+ * length, then the whole segment is returned. The segment coordinates are copied into the
+ * coords array.
+ *
+ * @return the segment type
+ */
+ public int currentSegment(float[] coords, float length) {
+ int type = currentSegment(coords);
+ // If the length is greater than the current segment length, no need to find
+ // the cut point. Same if this is a SEG_MOVETO.
+ if (mCurrentSegmentLength <= length || type == SEG_MOVETO) {
+ return type;
+ }
+
+ float t = length / getCurrentSegmentLength();
+
+ // We find at which offset the end point is located within the coords array and set
+ // a new end point to cut the segment short
+ switch (type) {
+ case SEG_CUBICTO:
+ case SEG_QUADTO:
+ float[] curve = new float[8];
+ curve[0] = mLastPoint[0];
+ curve[1] = mLastPoint[1];
+ System.arraycopy(coords, 0, curve, 2, coords.length);
+ if (type == SEG_CUBICTO) {
+ cubicCurveSegment(curve, 0f, t);
+ } else {
+ quadCurveSegment(curve, 0f, t);
+ }
+ System.arraycopy(curve, 2, coords, 0, coords.length);
+ break;
+ default:
+ float[] point = new float[2];
+ getPointAtLength(type, coords, mLastPoint[0], mLastPoint[1], t, point);
+ coords[0] = point[0];
+ coords[1] = point[1];
+ }
+
+ return type;
+ }
+
+ /** Returns the total length of the path */
+ public float getTotalLength() {
+ return mTotalLength;
+ }
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/Converter.java b/shadows/framework/src/main/java/org/robolectric/shadows/Converter.java
index e7f4060dd..4bfe1a45f 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/Converter.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/Converter.java
@@ -270,7 +270,7 @@ public class Converter<T> {
try {
typedValue.data = findValueFor(data);
} catch (Resources.NotFoundException e) {
- typedValue.data = Integer.decode(data);
+ typedValue.data = convertInt(data);
}
typedValue.assetCookie = 0;
typedValue.string = null;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/LegacyManifestParser.java b/shadows/framework/src/main/java/org/robolectric/shadows/LegacyManifestParser.java
index 6c071c311..a57d96989 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/LegacyManifestParser.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/LegacyManifestParser.java
@@ -183,6 +183,7 @@ public class LegacyManifestParser {
activityInfo.targetActivity = data.getTargetActivityName();
activityInfo.exported = data.isExported();
activityInfo.permission = data.getPermission();
+ activityInfo.enabled = data.isEnabled();
String themeRef;
// Based on ShadowActivity
@@ -231,6 +232,7 @@ public class LegacyManifestParser {
info.readPermission = data.getReadPermission();
info.writePermission = data.getWritePermission();
info.grantUriPermissions = data.getGrantUriPermissions();
+ info.enabled = data.isEnabled();
pkg.providers.add(createProvider(pkg, info));
}
@@ -239,7 +241,7 @@ public class LegacyManifestParser {
populateComponentInfo(info, pkg, data);
info.permission = data.getPermission();
info.exported = data.isExported();
-
+ info.enabled = data.isEnabled();
Activity receiver = createActivity(pkg, info);
for (IntentFilterData intentFilterData : data.getIntentFilters()) {
ActivityIntentInfo outInfo = new ActivityIntentInfo(receiver);
@@ -254,6 +256,7 @@ public class LegacyManifestParser {
populateComponentInfo(info, pkg, data);
info.permission = data.getPermission();
info.exported = data.isExported();
+ info.enabled = data.isEnabled();
Service service = createService(pkg, info);
for (IntentFilterData intentFilterData : data.getIntentFilters()) {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/RoundRectangle.java b/shadows/framework/src/main/java/org/robolectric/shadows/RoundRectangle.java
new file mode 100644
index 000000000..f396f43b7
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/RoundRectangle.java
@@ -0,0 +1,353 @@
+package org.robolectric.shadows;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RectangularShape;
+import java.awt.geom.RoundRectangle2D;
+import java.util.EnumSet;
+import java.util.NoSuchElementException;
+
+/**
+ * Defines a rectangle with rounded corners, where the sizes of the corners are potentially
+ * different.
+ *
+ * <p>Copied from
+ * https://github.com/aosp-mirror/platform_frameworks_base/blob/oreo-release/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java
+ */
+public class RoundRectangle extends RectangularShape {
+ public double x;
+ public double y;
+ public double width;
+ public double height;
+ public double ulWidth;
+ public double ulHeight;
+ public double urWidth;
+ public double urHeight;
+ public double lrWidth;
+ public double lrHeight;
+ public double llWidth;
+ public double llHeight;
+
+ private enum Zone {
+ CLOSE_OUTSIDE,
+ CLOSE_INSIDE,
+ MIDDLE,
+ FAR_INSIDE,
+ FAR_OUTSIDE
+ }
+
+ private final EnumSet<Zone> close = EnumSet.of(Zone.CLOSE_OUTSIDE, Zone.CLOSE_INSIDE);
+ private final EnumSet<Zone> far = EnumSet.of(Zone.FAR_OUTSIDE, Zone.FAR_INSIDE);
+
+ /**
+ * @param cornerDimensions array of 8 floating-point number corresponding to the width and the
+ * height of each corner in the following order: upper-left, upper-right, lower-right,
+ * lower-left. It assumes for the size the same convention as {@link RoundRectangle2D}, that
+ * is that the width and height of a corner correspond to the total width and height of the
+ * ellipse that corner is a quarter of.
+ */
+ public RoundRectangle(float x, float y, float width, float height, float[] cornerDimensions) {
+ assert cornerDimensions.length == 8
+ : "The array of corner dimensions must have eight " + "elements";
+
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+
+ float[] dimensions = cornerDimensions.clone();
+ // If a value is negative, the corresponding corner is squared
+ for (int i = 0; i < dimensions.length; i += 2) {
+ if (dimensions[i] < 0 || dimensions[i + 1] < 0) {
+ dimensions[i] = 0;
+ dimensions[i + 1] = 0;
+ }
+ }
+
+ double topCornerWidth = (dimensions[0] + dimensions[2]) / 2d;
+ double bottomCornerWidth = (dimensions[4] + dimensions[6]) / 2d;
+ double leftCornerHeight = (dimensions[1] + dimensions[7]) / 2d;
+ double rightCornerHeight = (dimensions[3] + dimensions[5]) / 2d;
+
+ // Rescale the corner dimensions if they are bigger than the rectangle
+ double scale = Math.min(1.0, width / topCornerWidth);
+ scale = Math.min(scale, width / bottomCornerWidth);
+ scale = Math.min(scale, height / leftCornerHeight);
+ scale = Math.min(scale, height / rightCornerHeight);
+
+ this.ulWidth = dimensions[0] * scale;
+ this.ulHeight = dimensions[1] * scale;
+ this.urWidth = dimensions[2] * scale;
+ this.urHeight = dimensions[3] * scale;
+ this.lrWidth = dimensions[4] * scale;
+ this.lrHeight = dimensions[5] * scale;
+ this.llWidth = dimensions[6] * scale;
+ this.llHeight = dimensions[7] * scale;
+ }
+
+ @Override
+ public double getX() {
+ return x;
+ }
+
+ @Override
+ public double getY() {
+ return y;
+ }
+
+ @Override
+ public double getWidth() {
+ return width;
+ }
+
+ @Override
+ public double getHeight() {
+ return height;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return (width <= 0d) || (height <= 0d);
+ }
+
+ @Override
+ public void setFrame(double x, double y, double w, double h) {
+ this.x = x;
+ this.y = y;
+ this.width = w;
+ this.height = h;
+ }
+
+ @Override
+ public Rectangle2D getBounds2D() {
+ return new Rectangle2D.Double(x, y, width, height);
+ }
+
+ @Override
+ public boolean contains(double x, double y) {
+ if (isEmpty()) {
+ return false;
+ }
+
+ double x0 = getX();
+ double y0 = getY();
+ double x1 = x0 + getWidth();
+ double y1 = y0 + getHeight();
+ // Check for trivial rejection - point is outside bounding rectangle
+ if (x < x0 || y < y0 || x >= x1 || y >= y1) {
+ return false;
+ }
+
+ double insideTopX0 = x0 + ulWidth / 2d;
+ double insideLeftY0 = y0 + ulHeight / 2d;
+ if (x < insideTopX0 && y < insideLeftY0) {
+ // In the upper-left corner
+ return isInsideCorner(x - insideTopX0, y - insideLeftY0, ulWidth / 2d, ulHeight / 2d);
+ }
+
+ double insideTopX1 = x1 - urWidth / 2d;
+ double insideRightY0 = y0 + urHeight / 2d;
+ if (x > insideTopX1 && y < insideRightY0) {
+ // In the upper-right corner
+ return isInsideCorner(x - insideTopX1, y - insideRightY0, urWidth / 2d, urHeight / 2d);
+ }
+
+ double insideBottomX1 = x1 - lrWidth / 2d;
+ double insideRightY1 = y1 - lrHeight / 2d;
+ if (x > insideBottomX1 && y > insideRightY1) {
+ // In the lower-right corner
+ return isInsideCorner(x - insideBottomX1, y - insideRightY1, lrWidth / 2d, lrHeight / 2d);
+ }
+
+ double insideBottomX0 = x0 + llWidth / 2d;
+ double insideLeftY1 = y1 - llHeight / 2d;
+ if (x < insideBottomX0 && y > insideLeftY1) {
+ // In the lower-left corner
+ return isInsideCorner(x - insideBottomX0, y - insideLeftY1, llWidth / 2d, llHeight / 2d);
+ }
+
+ // In the central part of the rectangle
+ return true;
+ }
+
+ private boolean isInsideCorner(double x, double y, double width, double height) {
+ double squareDist = height * height * x * x + width * width * y * y;
+ return squareDist <= width * width * height * height;
+ }
+
+ private Zone classify(
+ double coord, double side1, double arcSize1, double side2, double arcSize2) {
+ if (coord < side1) {
+ return Zone.CLOSE_OUTSIDE;
+ } else if (coord < side1 + arcSize1) {
+ return Zone.CLOSE_INSIDE;
+ } else if (coord < side2 - arcSize2) {
+ return Zone.MIDDLE;
+ } else if (coord < side2) {
+ return Zone.FAR_INSIDE;
+ } else {
+ return Zone.FAR_OUTSIDE;
+ }
+ }
+
+ public boolean intersects(double x, double y, double w, double h) {
+ if (isEmpty() || w <= 0 || h <= 0) {
+ return false;
+ }
+ double x0 = getX();
+ double y0 = getY();
+ double x1 = x0 + getWidth();
+ double y1 = y0 + getHeight();
+ // Check for trivial rejection - bounding rectangles do not intersect
+ if (x + w <= x0 || x >= x1 || y + h <= y0 || y >= y1) {
+ return false;
+ }
+
+ double maxLeftCornerWidth = Math.max(ulWidth, llWidth) / 2d;
+ double maxRightCornerWidth = Math.max(urWidth, lrWidth) / 2d;
+ double maxUpperCornerHeight = Math.max(ulHeight, urHeight) / 2d;
+ double maxLowerCornerHeight = Math.max(llHeight, lrHeight) / 2d;
+ Zone x0class = classify(x, x0, maxLeftCornerWidth, x1, maxRightCornerWidth);
+ Zone x1class = classify(x + w, x0, maxLeftCornerWidth, x1, maxRightCornerWidth);
+ Zone y0class = classify(y, y0, maxUpperCornerHeight, y1, maxLowerCornerHeight);
+ Zone y1class = classify(y + h, y0, maxUpperCornerHeight, y1, maxLowerCornerHeight);
+
+ // Trivially accept if any point is inside inner rectangle
+ if (x0class == Zone.MIDDLE
+ || x1class == Zone.MIDDLE
+ || y0class == Zone.MIDDLE
+ || y1class == Zone.MIDDLE) {
+ return true;
+ }
+ // Trivially accept if either edge spans inner rectangle
+ if ((close.contains(x0class) && far.contains(x1class))
+ || (close.contains(y0class) && far.contains(y1class))) {
+ return true;
+ }
+
+ // Since neither edge spans the center, then one of the corners
+ // must be in one of the rounded edges. We detect this case if
+ // a [xy]0class is 3 or a [xy]1class is 1. One of those two cases
+ // must be true for each direction.
+ // We now find a "nearest point" to test for being inside a rounded
+ // corner.
+ if (x1class == Zone.CLOSE_INSIDE && y1class == Zone.CLOSE_INSIDE) {
+ // Potentially in upper-left corner
+ x = x + w - x0 - ulWidth / 2d;
+ y = y + h - y0 - ulHeight / 2d;
+ return x > 0 || y > 0 || isInsideCorner(x, y, ulWidth / 2d, ulHeight / 2d);
+ }
+ if (x1class == Zone.CLOSE_INSIDE) {
+ // Potentially in lower-left corner
+ x = x + w - x0 - llWidth / 2d;
+ y = y - y1 + llHeight / 2d;
+ return x > 0 || y < 0 || isInsideCorner(x, y, llWidth / 2d, llHeight / 2d);
+ }
+ if (y1class == Zone.CLOSE_INSIDE) {
+ // Potentially in the upper-right corner
+ x = x - x1 + urWidth / 2d;
+ y = y + h - y0 - urHeight / 2d;
+ return x < 0 || y > 0 || isInsideCorner(x, y, urWidth / 2d, urHeight / 2d);
+ }
+ // Potentially in the lower-right corner
+ x = x - x1 + lrWidth / 2d;
+ y = y - y1 + lrHeight / 2d;
+ return x < 0 || y < 0 || isInsideCorner(x, y, lrWidth / 2d, lrHeight / 2d);
+ }
+
+ @Override
+ public boolean contains(double x, double y, double w, double h) {
+ if (isEmpty() || w <= 0 || h <= 0) {
+ return false;
+ }
+ return (contains(x, y) && contains(x + w, y) && contains(x, y + h) && contains(x + w, y + h));
+ }
+
+ @Override
+ public PathIterator getPathIterator(final AffineTransform at) {
+ return new PathIterator() {
+ int index;
+
+ // ArcIterator.btan(Math.PI/2)
+ public static final double CtrlVal = 0.5522847498307933;
+ private final double ncv = 1.0 - CtrlVal;
+
+ // Coordinates of control points for Bezier curves approximating the straight lines
+ // and corners of the rounded rectangle.
+ private final double[][] ctrlpts = {
+ {0.0, 0.0, 0.0, ulHeight},
+ {0.0, 0.0, 1.0, -llHeight},
+ {0.0, 0.0, 1.0, -llHeight * ncv, 0.0, ncv * llWidth, 1.0, 0.0, 0.0, llWidth, 1.0, 0.0},
+ {1.0, -lrWidth, 1.0, 0.0},
+ {1.0, -lrWidth * ncv, 1.0, 0.0, 1.0, 0.0, 1.0, -lrHeight * ncv, 1.0, 0.0, 1.0, -lrHeight},
+ {1.0, 0.0, 0.0, urHeight},
+ {1.0, 0.0, 0.0, ncv * urHeight, 1.0, -urWidth * ncv, 0.0, 0.0, 1.0, -urWidth, 0.0, 0.0},
+ {0.0, ulWidth, 0.0, 0.0},
+ {0.0, ncv * ulWidth, 0.0, 0.0, 0.0, 0.0, 0.0, ncv * ulHeight, 0.0, 0.0, 0.0, ulHeight},
+ {}
+ };
+ private final int[] types = {
+ SEG_MOVETO,
+ SEG_LINETO,
+ SEG_CUBICTO,
+ SEG_LINETO,
+ SEG_CUBICTO,
+ SEG_LINETO,
+ SEG_CUBICTO,
+ SEG_LINETO,
+ SEG_CUBICTO,
+ SEG_CLOSE,
+ };
+
+ @Override
+ public int getWindingRule() {
+ return WIND_NON_ZERO;
+ }
+
+ @Override
+ public boolean isDone() {
+ return index >= ctrlpts.length;
+ }
+
+ @Override
+ public void next() {
+ index++;
+ }
+
+ @Override
+ public int currentSegment(float[] coords) {
+ if (isDone()) {
+ throw new NoSuchElementException("roundrect iterator out of bounds");
+ }
+ int nc = 0;
+ double ctrls[] = ctrlpts[index];
+ for (int i = 0; i < ctrls.length; i += 4) {
+ coords[nc++] = (float) (x + ctrls[i] * width + ctrls[i + 1] / 2d);
+ coords[nc++] = (float) (y + ctrls[i + 2] * height + ctrls[i + 3] / 2d);
+ }
+ if (at != null) {
+ at.transform(coords, 0, coords, 0, nc / 2);
+ }
+ return types[index];
+ }
+
+ @Override
+ public int currentSegment(double[] coords) {
+ if (isDone()) {
+ throw new NoSuchElementException("roundrect iterator out of bounds");
+ }
+ int nc = 0;
+ double ctrls[] = ctrlpts[index];
+ for (int i = 0; i < ctrls.length; i += 4) {
+ coords[nc++] = x + ctrls[i] * width + ctrls[i + 1] / 2d;
+ coords[nc++] = y + ctrls[i + 2] * height + ctrls[i + 3] / 2d;
+ }
+ if (at != null) {
+ at.transform(coords, 0, coords, 0, nc / 2);
+ }
+ return types[index];
+ }
+ };
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAbsListView.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAbsListView.java
index 5b2d8e1b9..279448e79 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAbsListView.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAbsListView.java
@@ -12,17 +12,17 @@ public class ShadowAbsListView extends ShadowAdapterView {
private int lastSmoothScrollByDuration;
@Implementation
- public void setOnScrollListener(AbsListView.OnScrollListener l) {
+ protected void setOnScrollListener(AbsListView.OnScrollListener l) {
onScrollListener = l;
}
@Implementation
- public void smoothScrollToPosition(int position) {
+ protected void smoothScrollToPosition(int position) {
smoothScrolledPosition = position;
}
@Implementation
- public void smoothScrollBy(int distance, int duration) {
+ protected void smoothScrollBy(int distance, int duration) {
this.lastSmoothScrollByDistance = distance;
this.lastSmoothScrollByDuration = duration;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAbsSpinner.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAbsSpinner.java
index ef56403ca..a87d0c383 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAbsSpinner.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAbsSpinner.java
@@ -16,13 +16,13 @@ public class ShadowAbsSpinner extends ShadowAdapterView {
private boolean animatedTransition;
@Implementation
- public void setSelection(int position, boolean animate) {
+ protected void setSelection(int position, boolean animate) {
directlyOn(realAbsSpinner, AbsSpinner.class, "setSelection", ClassParameter.from(int.class, position), ClassParameter.from(boolean.class, animate));
animatedTransition = animate;
}
@Implementation
- public void setSelection(int position) {
+ protected void setSelection(int position) {
directlyOn(realAbsSpinner, AbsSpinner.class, "setSelection", ClassParameter.from(int.class, position));
SpinnerAdapter adapter = realAbsSpinner.getAdapter();
if (getItemSelectedListener() != null && adapter != null) {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityManager.java
index 7fb6f05ac..db0136329 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityManager.java
@@ -71,17 +71,19 @@ public class ShadowAccessibilityManager {
}
@Implementation
- public boolean addAccessibilityStateChangeListener(AccessibilityManager.AccessibilityStateChangeListener listener) {
+ protected boolean addAccessibilityStateChangeListener(
+ AccessibilityManager.AccessibilityStateChangeListener listener) {
return true;
}
@Implementation
- public boolean removeAccessibilityStateChangeListener(AccessibilityManager.AccessibilityStateChangeListener listener) {
+ protected boolean removeAccessibilityStateChangeListener(
+ AccessibilityManager.AccessibilityStateChangeListener listener) {
return true;
}
@Implementation
- public List<ServiceInfo> getAccessibilityServiceList () {
+ protected List<ServiceInfo> getAccessibilityServiceList() {
return accessibilityServiceList;
}
@@ -90,7 +92,8 @@ public class ShadowAccessibilityManager {
}
@Implementation
- public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList (int feedbackTypeFlags) {
+ protected List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(
+ int feedbackTypeFlags) {
return enabledAccessibilityServiceList;
}
@@ -99,7 +102,7 @@ public class ShadowAccessibilityManager {
}
@Implementation
- public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList () {
+ protected List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() {
return installedAccessibilityServiceList;
}
@@ -108,7 +111,7 @@ public class ShadowAccessibilityManager {
}
@Implementation
- public boolean isEnabled () {
+ protected boolean isEnabled() {
return enabled;
}
@@ -118,7 +121,7 @@ public class ShadowAccessibilityManager {
}
@Implementation
- public boolean isTouchExplorationEnabled () {
+ protected boolean isTouchExplorationEnabled() {
return touchExplorationEnabled;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityNodeInfo.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityNodeInfo.java
index 770481421..24ad675ad 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityNodeInfo.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityNodeInfo.java
@@ -184,12 +184,12 @@ public class ShadowAccessibilityNodeInfo {
private AccessibilityNodeInfo realAccessibilityNodeInfo;
@Implementation
- public void __constructor__() {
+ protected void __constructor__() {
ReflectionHelpers.setStaticField(AccessibilityNodeInfo.class, "CREATOR", ShadowAccessibilityNodeInfo.CREATOR);
}
@Implementation
- public static AccessibilityNodeInfo obtain(AccessibilityNodeInfo info) {
+ protected static AccessibilityNodeInfo obtain(AccessibilityNodeInfo info) {
final ShadowAccessibilityNodeInfo shadowInfo = Shadow.extract(info);
final AccessibilityNodeInfo obtainedInstance = shadowInfo.getClone();
@@ -204,7 +204,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public static AccessibilityNodeInfo obtain(View view) {
+ protected static AccessibilityNodeInfo obtain(View view) {
// We explicitly avoid allocating the AccessibilityNodeInfo from the actual pool by using the
// private constructor. Not doing so affects test suites which use both shadow and
// non-shadow objects.
@@ -235,12 +235,12 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public static AccessibilityNodeInfo obtain() {
+ protected static AccessibilityNodeInfo obtain() {
return obtain(new View(RuntimeEnvironment.application.getApplicationContext()));
}
@Implementation
- public static AccessibilityNodeInfo obtain(View root, int virtualDescendantId) {
+ protected static AccessibilityNodeInfo obtain(View root, int virtualDescendantId) {
AccessibilityNodeInfo node = obtain(root);
return node;
}
@@ -281,7 +281,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public void recycle() {
+ protected void recycle() {
final StrictEqualityNodeWrapper wrapper =
new StrictEqualityNodeWrapper(realAccessibilityNodeInfo);
if (!obtainedInstances.containsKey(wrapper)) {
@@ -318,7 +318,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public int getChildCount() {
+ protected int getChildCount() {
if (children == null) {
return 0;
}
@@ -327,7 +327,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public AccessibilityNodeInfo getChild(int index) {
+ protected AccessibilityNodeInfo getChild(int index) {
if (children == null) {
return null;
}
@@ -341,7 +341,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public AccessibilityNodeInfo getParent() {
+ protected AccessibilityNodeInfo getParent() {
if (parent == null) {
return null;
}
@@ -350,7 +350,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public boolean refresh() {
+ protected boolean refresh() {
return refreshReturnValue;
}
@@ -359,32 +359,32 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public boolean isClickable() {
+ protected boolean isClickable() {
return ((propertyFlags & CLICKABLE_MASK) != 0);
}
@Implementation
- public boolean isLongClickable() {
+ protected boolean isLongClickable() {
return ((propertyFlags & LONGCLICKABLE_MASK) != 0);
}
@Implementation
- public boolean isFocusable() {
+ protected boolean isFocusable() {
return ((propertyFlags & FOCUSABLE_MASK) != 0);
}
@Implementation
- public boolean isFocused() {
+ protected boolean isFocused() {
return ((propertyFlags & FOCUSED_MASK) != 0);
}
@Implementation
- public boolean isVisibleToUser() {
+ protected boolean isVisibleToUser() {
return ((propertyFlags & VISIBLE_TO_USER_MASK) != 0);
}
@Implementation
- public boolean isScrollable() {
+ protected boolean isScrollable() {
return ((propertyFlags & SCROLLABLE_MASK) != 0);
}
@@ -393,7 +393,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public boolean isEditable() {
+ protected boolean isEditable() {
return ((propertyFlags & EDITABLE_MASK) != 0);
}
@@ -402,112 +402,112 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public boolean isCheckable() {
+ protected boolean isCheckable() {
return ((propertyFlags & CHECKABLE_MASK) != 0);
}
@Implementation
- public void setCheckable(boolean checkable) {
+ protected void setCheckable(boolean checkable) {
propertyFlags = (propertyFlags & ~CHECKABLE_MASK) |
(checkable ? CHECKABLE_MASK : 0);
}
@Implementation
- public void setChecked(boolean checked) {
+ protected void setChecked(boolean checked) {
propertyFlags = (propertyFlags & ~CHECKED_MASK) |
(checked ? CHECKED_MASK : 0);
}
@Implementation
- public boolean isChecked() {
+ protected boolean isChecked() {
return ((propertyFlags & CHECKED_MASK) != 0);
}
@Implementation
- public void setEnabled(boolean enabled) {
+ protected void setEnabled(boolean enabled) {
propertyFlags = (propertyFlags & ~ENABLED_MASK) |
(enabled ? ENABLED_MASK : 0);
}
@Implementation
- public boolean isEnabled() {
+ protected boolean isEnabled() {
return ((propertyFlags & ENABLED_MASK) != 0);
}
@Implementation
- public void setPassword(boolean password) {
+ protected void setPassword(boolean password) {
propertyFlags = (propertyFlags & ~PASSWORD_MASK) |
(password ? PASSWORD_MASK : 0);
}
@Implementation
- public boolean isPassword() {
+ protected boolean isPassword() {
return ((propertyFlags & PASSWORD_MASK) != 0);
}
@Implementation
- public void setSelected(boolean selected) {
+ protected void setSelected(boolean selected) {
propertyFlags = (propertyFlags & ~SELECTED_MASK) |
(selected ? SELECTED_MASK : 0);
}
@Implementation
- public boolean isSelected() {
+ protected boolean isSelected() {
return ((propertyFlags & SELECTED_MASK) != 0);
}
@Implementation
- public void setAccessibilityFocused(boolean focused) {
+ protected void setAccessibilityFocused(boolean focused) {
propertyFlags = (propertyFlags & ~A11YFOCUSED_MASK) |
(focused ? A11YFOCUSED_MASK : 0);
}
@Implementation
- public boolean isAccessibilityFocused() {
+ protected boolean isAccessibilityFocused() {
return ((propertyFlags & A11YFOCUSED_MASK) != 0);
}
@Implementation(minSdk = LOLLIPOP)
- public void setMultiLine(boolean multiLine) {
+ protected void setMultiLine(boolean multiLine) {
propertyFlags = (propertyFlags & ~MULTILINE_MASK) |
(multiLine ? MULTILINE_MASK : 0);
}
@Implementation(minSdk = LOLLIPOP)
- public boolean isMultiLine() {
+ protected boolean isMultiLine() {
return ((propertyFlags & MULTILINE_MASK) != 0);
}
@Implementation(minSdk = LOLLIPOP)
- public void setContentInvalid(boolean contentInvalid) {
+ protected void setContentInvalid(boolean contentInvalid) {
propertyFlags = (propertyFlags & ~CONTENT_INVALID_MASK) |
(contentInvalid ? CONTENT_INVALID_MASK : 0);
}
@Implementation(minSdk = LOLLIPOP)
- public boolean isContentInvalid() {
+ protected boolean isContentInvalid() {
return ((propertyFlags & CONTENT_INVALID_MASK) != 0);
}
@Implementation(minSdk = LOLLIPOP)
- public void setDismissable(boolean dismissable) {
+ protected void setDismissable(boolean dismissable) {
propertyFlags = (propertyFlags & ~DISMISSABLE_MASK) |
(dismissable ? DISMISSABLE_MASK : 0);
}
@Implementation(minSdk = LOLLIPOP)
- public boolean isDismissable() {
+ protected boolean isDismissable() {
return ((propertyFlags & DISMISSABLE_MASK) != 0);
}
@Implementation(minSdk = LOLLIPOP)
- public void setCanOpenPopup(boolean opensPopup) {
+ protected void setCanOpenPopup(boolean opensPopup) {
propertyFlags = (propertyFlags & ~CAN_OPEN_POPUP_MASK) |
(opensPopup ? CAN_OPEN_POPUP_MASK : 0);
}
@Implementation(minSdk = LOLLIPOP)
- public boolean canOpenPopup() {
+ protected boolean canOpenPopup() {
return ((propertyFlags & CAN_OPEN_POPUP_MASK) != 0);
}
@@ -517,28 +517,28 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public void setClickable(boolean isClickable) {
+ protected void setClickable(boolean isClickable) {
propertyFlags = (propertyFlags & ~CLICKABLE_MASK) | (isClickable ? CLICKABLE_MASK : 0);
}
@Implementation
- public void setLongClickable(boolean isLongClickable) {
+ protected void setLongClickable(boolean isLongClickable) {
propertyFlags =
(propertyFlags & ~LONGCLICKABLE_MASK) | (isLongClickable ? LONGCLICKABLE_MASK : 0);
}
@Implementation
- public void setFocusable(boolean isFocusable) {
+ protected void setFocusable(boolean isFocusable) {
propertyFlags = (propertyFlags & ~FOCUSABLE_MASK) | (isFocusable ? FOCUSABLE_MASK : 0);
}
@Implementation
- public void setFocused(boolean isFocused) {
+ protected void setFocused(boolean isFocused) {
propertyFlags = (propertyFlags & ~FOCUSED_MASK) | (isFocused ? FOCUSED_MASK : 0);
}
@Implementation
- public void setScrollable(boolean isScrollable) {
+ protected void setScrollable(boolean isScrollable) {
propertyFlags = (propertyFlags & ~SCROLLABLE_MASK) | (isScrollable ? SCROLLABLE_MASK : 0);
}
@@ -547,48 +547,48 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public void setEditable(boolean isEditable) {
+ protected void setEditable(boolean isEditable) {
propertyFlags = (propertyFlags & ~EDITABLE_MASK) | (isEditable ? EDITABLE_MASK : 0);
}
@Implementation
- public void setVisibleToUser(boolean isVisibleToUser) {
+ protected void setVisibleToUser(boolean isVisibleToUser) {
propertyFlags =
(propertyFlags & ~VISIBLE_TO_USER_MASK) | (isVisibleToUser ? VISIBLE_TO_USER_MASK : 0);
}
@Implementation
- public void setContentDescription(CharSequence description) {
+ protected void setContentDescription(CharSequence description) {
contentDescription = description;
}
@Implementation
- public CharSequence getContentDescription() {
+ protected CharSequence getContentDescription() {
return contentDescription;
}
@Implementation
- public void setClassName(CharSequence name) {
+ protected void setClassName(CharSequence name) {
className = name;
}
@Implementation
- public CharSequence getClassName() {
+ protected CharSequence getClassName() {
return className;
}
@Implementation
- public void setText(CharSequence t) {
+ protected void setText(CharSequence t) {
text = t;
}
@Implementation
- public CharSequence getText() {
+ protected CharSequence getText() {
return text;
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public void setTextSelection(int start, int end) {
+ protected void setTextSelection(int start, int end) {
textSelectionStart = start;
textSelectionEnd = end;
}
@@ -599,7 +599,7 @@ public class ShadowAccessibilityNodeInfo {
* @return The text selection start if there is selection or UNDEFINED_SELECTION_INDEX.
*/
@Implementation(minSdk = JELLY_BEAN_MR2)
- public int getTextSelectionStart() {
+ protected int getTextSelectionStart() {
return textSelectionStart;
}
@@ -609,12 +609,12 @@ public class ShadowAccessibilityNodeInfo {
* @return The text selection end if there is selection or UNDEFINED_SELECTION_INDEX.
*/
@Implementation(minSdk = JELLY_BEAN_MR2)
- public int getTextSelectionEnd() {
+ protected int getTextSelectionEnd() {
return textSelectionEnd;
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public AccessibilityNodeInfo getLabelFor() {
+ protected AccessibilityNodeInfo getLabelFor() {
if (labelFor == null) {
return null;
}
@@ -631,7 +631,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation(minSdk = JELLY_BEAN_MR1)
- public AccessibilityNodeInfo getLabeledBy() {
+ protected AccessibilityNodeInfo getLabeledBy() {
if (labeledBy == null) {
return null;
}
@@ -648,107 +648,107 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public int getMovementGranularities() {
+ protected int getMovementGranularities() {
return movementGranularities;
}
@Implementation
- public void setMovementGranularities(int movementGranularities) {
+ protected void setMovementGranularities(int movementGranularities) {
this.movementGranularities = movementGranularities;
}
@Implementation
- public CharSequence getPackageName() {
+ protected CharSequence getPackageName() {
return packageName;
}
@Implementation
- public void setPackageName(CharSequence packageName) {
+ protected void setPackageName(CharSequence packageName) {
this.packageName = packageName;
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public String getViewIdResourceName() {
+ protected String getViewIdResourceName() {
return viewIdResourceName;
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public void setViewIdResourceName(String viewIdResourceName) {
+ protected void setViewIdResourceName(String viewIdResourceName) {
this.viewIdResourceName = viewIdResourceName;
}
@Implementation(minSdk = KITKAT)
- public CollectionInfo getCollectionInfo() {
+ protected CollectionInfo getCollectionInfo() {
return collectionInfo;
}
@Implementation(minSdk = KITKAT)
- public void setCollectionInfo(CollectionInfo collectionInfo) {
+ protected void setCollectionInfo(CollectionInfo collectionInfo) {
this.collectionInfo = collectionInfo;
}
@Implementation(minSdk = KITKAT)
- public CollectionItemInfo getCollectionItemInfo() {
+ protected CollectionItemInfo getCollectionItemInfo() {
return collectionItemInfo;
}
@Implementation(minSdk = KITKAT)
- public void setCollectionItemInfo(CollectionItemInfo collectionItemInfo) {
+ protected void setCollectionItemInfo(CollectionItemInfo collectionItemInfo) {
this.collectionItemInfo = collectionItemInfo;
}
@Implementation(minSdk = KITKAT)
- public int getInputType() {
+ protected int getInputType() {
return inputType;
}
@Implementation(minSdk = KITKAT)
- public void setInputType(int inputType) {
+ protected void setInputType(int inputType) {
this.inputType = inputType;
}
@Implementation(minSdk = KITKAT)
- public int getLiveRegion() {
+ protected int getLiveRegion() {
return liveRegion;
}
@Implementation(minSdk = KITKAT)
- public void setLiveRegion(int liveRegion) {
+ protected void setLiveRegion(int liveRegion) {
this.liveRegion = liveRegion;
}
@Implementation(minSdk = KITKAT)
- public RangeInfo getRangeInfo() {
+ protected RangeInfo getRangeInfo() {
return rangeInfo;
}
@Implementation(minSdk = KITKAT)
- public void setRangeInfo(RangeInfo rangeInfo) {
+ protected void setRangeInfo(RangeInfo rangeInfo) {
this.rangeInfo = rangeInfo;
}
@Implementation(minSdk = LOLLIPOP)
- public int getMaxTextLength() {
+ protected int getMaxTextLength() {
return maxTextLength;
}
@Implementation(minSdk = LOLLIPOP)
- public void setMaxTextLength(int maxTextLength) {
+ protected void setMaxTextLength(int maxTextLength) {
this.maxTextLength = maxTextLength;
}
@Implementation(minSdk = LOLLIPOP)
- public CharSequence getError() {
+ protected CharSequence getError() {
return error;
}
@Implementation(minSdk = LOLLIPOP)
- public void setError(CharSequence error) {
+ protected void setError(CharSequence error) {
this.error = error;
}
@Implementation(minSdk = LOLLIPOP_MR1)
- public AccessibilityNodeInfo getTraversalAfter() {
+ protected AccessibilityNodeInfo getTraversalAfter() {
if (traversalAfter == null) {
return null;
}
@@ -783,7 +783,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation(minSdk = LOLLIPOP_MR1)
- public AccessibilityNodeInfo getTraversalBefore() {
+ protected AccessibilityNodeInfo getTraversalBefore() {
if (traversalBefore == null) {
return null;
}
@@ -818,17 +818,17 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public void setSource (View source) {
+ protected void setSource(View source) {
this.view = source;
}
@Implementation
- public void setSource (View root, int virtualDescendantId) {
+ protected void setSource(View root, int virtualDescendantId) {
this.view = root;
}
@Implementation
- public void getBoundsInScreen(Rect outBounds) {
+ protected void getBoundsInScreen(Rect outBounds) {
if (boundsInScreen == null) {
boundsInScreen = new Rect();
}
@@ -836,7 +836,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public void getBoundsInParent(Rect outBounds) {
+ protected void getBoundsInParent(Rect outBounds) {
if (boundsInParent == null) {
boundsInParent = new Rect();
}
@@ -844,7 +844,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public void setBoundsInScreen(Rect b) {
+ protected void setBoundsInScreen(Rect b) {
if (boundsInScreen == null) {
boundsInScreen = new Rect(b);
} else {
@@ -853,7 +853,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public void setBoundsInParent(Rect b) {
+ protected void setBoundsInParent(Rect b) {
if (boundsInParent == null) {
boundsInParent = new Rect(b);
} else {
@@ -862,7 +862,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public void addAction(int action) {
+ protected void addAction(int action) {
if (getApiLevel() >= LOLLIPOP) {
if ((action & getActionTypeMaskFromFramework()) != 0) {
throw new IllegalArgumentException("Action is not a combination of the standard " +
@@ -881,7 +881,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation(minSdk = LOLLIPOP)
- public void addAction(AccessibilityAction action) {
+ protected void addAction(AccessibilityAction action) {
if (action == null) {
return;
}
@@ -894,13 +894,13 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation(minSdk = LOLLIPOP)
- public void removeAction(int action) {
+ protected void removeAction(int action) {
AccessibilityAction convertedAction = getActionFromIdFromFrameWork(action);
removeAction(convertedAction);
}
@Implementation(minSdk = LOLLIPOP)
- public boolean removeAction(AccessibilityAction action) {
+ protected boolean removeAction(AccessibilityAction action) {
if (action == null || actionsArray == null) {
return false;
}
@@ -908,20 +908,17 @@ public class ShadowAccessibilityNodeInfo {
}
/**
- * Obtain flags for actions supported. Currently only supports
- * {@link AccessibilityNodeInfo#ACTION_CLICK},
- * {@link AccessibilityNodeInfo#ACTION_LONG_CLICK},
- * {@link AccessibilityNodeInfo#ACTION_SCROLL_FORWARD},
- * {@link AccessibilityNodeInfo#ACTION_PASTE},
- * {@link AccessibilityNodeInfo#ACTION_FOCUS},
- * {@link AccessibilityNodeInfo#ACTION_SET_SELECTION},
- * {@link AccessibilityNodeInfo#ACTION_SCROLL_BACKWARD}
- * Returned value is derived from the getters.
+ * Obtain flags for actions supported. Currently only supports {@link
+ * AccessibilityNodeInfo#ACTION_CLICK}, {@link AccessibilityNodeInfo#ACTION_LONG_CLICK}, {@link
+ * AccessibilityNodeInfo#ACTION_SCROLL_FORWARD}, {@link AccessibilityNodeInfo#ACTION_PASTE},
+ * {@link AccessibilityNodeInfo#ACTION_FOCUS}, {@link AccessibilityNodeInfo#ACTION_SET_SELECTION},
+ * {@link AccessibilityNodeInfo#ACTION_SCROLL_BACKWARD} Returned value is derived from the
+ * getters.
*
* @return Action mask. 0 if no actions supported.
*/
@Implementation
- public int getActions() {
+ protected int getActions() {
if (getApiLevel() >= LOLLIPOP) {
int returnValue = 0;
if (actionsArray == null) {
@@ -955,7 +952,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation(minSdk = LOLLIPOP)
- public AccessibilityWindowInfo getWindow() {
+ protected AccessibilityWindowInfo getWindow() {
return accessibilityWindowInfo;
}
@@ -970,7 +967,7 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation(minSdk = LOLLIPOP)
- public List<AccessibilityAction> getActionList() {
+ protected List<AccessibilityAction> getActionList() {
if (actionsArray == null) {
return Collections.emptyList();
}
@@ -979,12 +976,12 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public boolean performAction(int action) {
+ protected boolean performAction(int action) {
return performAction(action, null);
}
@Implementation
- public boolean performAction(int action, Bundle arguments) {
+ protected boolean performAction(int action, Bundle arguments) {
if (performedActionAndArgsList == null) {
performedActionAndArgsList = new ArrayList<>();
}
@@ -1043,13 +1040,13 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public void addChild(View child) {
+ protected void addChild(View child) {
AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(child);
addChild(node);
}
@Implementation
- public void addChild(View root, int virtualDescendantId) {
+ protected void addChild(View root, int virtualDescendantId) {
AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(root, virtualDescendantId);
addChild(node);
}
@@ -1194,7 +1191,7 @@ public class ShadowAccessibilityNodeInfo {
private CharSequence label;
@Implementation
- public void __constructor__(int id, CharSequence label) {
+ protected void __constructor__(int id, CharSequence label) {
if (((id & (int)ReflectionHelpers.getStaticField(AccessibilityNodeInfo.class, "ACTION_TYPE_MASK")) == 0) && Integer.bitCount(id) != 1) {
throw new IllegalArgumentException("Invalid standard action id");
}
@@ -1203,12 +1200,12 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public int getId() {
+ protected int getId() {
return id;
}
@Implementation
- public CharSequence getLabel() {
+ protected CharSequence getLabel() {
return label;
}
@@ -1240,12 +1237,12 @@ public class ShadowAccessibilityNodeInfo {
}
@Implementation
- public int describeContents() {
+ protected int describeContents() {
return 0;
}
@Implementation
- public void writeToParcel(Parcel dest, int flags) {
+ protected void writeToParcel(Parcel dest, int flags) {
StrictEqualityNodeWrapper wrapper = new StrictEqualityNodeWrapper(realAccessibilityNodeInfo);
int keyOfWrapper = -1;
for (int i = 0; i < orderedInstances.size(); i++) {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityRecord.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityRecord.java
index 11539a2be..1f7f1059c 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityRecord.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityRecord.java
@@ -25,7 +25,7 @@ public class ShadowAccessibilityRecord {
private int windowId = -1;
@Implementation
- public void setSource(View root, int virtualDescendantId) {
+ protected void setSource(View root, int virtualDescendantId) {
this.sourceRoot = root;
this.virtualDescendantId = virtualDescendantId;
Shadow.directlyOn(realRecord, AccessibilityRecord.class, "setSource",
@@ -34,7 +34,7 @@ public class ShadowAccessibilityRecord {
}
@Implementation
- public void setSource(View root) {
+ protected void setSource(View root) {
this.sourceRoot = root;
this.virtualDescendantId = NO_VIRTUAL_ID;
Shadow.directlyOn(realRecord, AccessibilityRecord.class, "setSource",
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityService.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityService.java
index 489c2f923..697a1e7e3 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityService.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityService.java
@@ -14,8 +14,8 @@ public class ShadowAccessibilityService extends ShadowService {
private final List<Integer> globalActionsPerformed = new ArrayList<>();
- @Implementation
- public final boolean performGlobalAction(int action) {
+ @Implementation
+ protected final boolean performGlobalAction(int action) {
globalActionsPerformed.add(action);
return true;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityWindowInfo.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityWindowInfo.java
index 8de6695e8..ea5584847 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityWindowInfo.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccessibilityWindowInfo.java
@@ -52,10 +52,10 @@ public class ShadowAccessibilityWindowInfo {
private AccessibilityWindowInfo mRealAccessibilityWindowInfo;
@Implementation
- public void __constructor__() {}
+ protected void __constructor__() {}
@Implementation
- public static AccessibilityWindowInfo obtain() {
+ protected static AccessibilityWindowInfo obtain() {
final AccessibilityWindowInfo obtainedInstance =
ReflectionHelpers.callConstructor(AccessibilityWindowInfo.class);
StrictEqualityWindowWrapper wrapper = new StrictEqualityWindowWrapper(obtainedInstance);
@@ -64,7 +64,7 @@ public class ShadowAccessibilityWindowInfo {
}
@Implementation
- public static AccessibilityWindowInfo obtain(AccessibilityWindowInfo window) {
+ protected static AccessibilityWindowInfo obtain(AccessibilityWindowInfo window) {
final ShadowAccessibilityWindowInfo shadowInfo = Shadow.extract(window);
final AccessibilityWindowInfo obtainedInstance = shadowInfo.getClone();
StrictEqualityWindowWrapper wrapper = new StrictEqualityWindowWrapper(obtainedInstance);
@@ -160,12 +160,12 @@ public class ShadowAccessibilityWindowInfo {
}
@Implementation
- public int getType() {
+ protected int getType() {
return type;
}
@Implementation
- public int getChildCount() {
+ protected int getChildCount() {
if (children == null) {
return 0;
}
@@ -174,7 +174,7 @@ public class ShadowAccessibilityWindowInfo {
}
@Implementation
- public AccessibilityWindowInfo getChild(int index) {
+ protected AccessibilityWindowInfo getChild(int index) {
if (children == null) {
return null;
}
@@ -183,27 +183,27 @@ public class ShadowAccessibilityWindowInfo {
}
@Implementation
- public AccessibilityWindowInfo getParent() {
+ protected AccessibilityWindowInfo getParent() {
return parent;
}
@Implementation
- public AccessibilityNodeInfo getRoot() {
+ protected AccessibilityNodeInfo getRoot() {
return (rootNode == null) ? null : AccessibilityNodeInfo.obtain(rootNode);
}
@Implementation
- public boolean isActive() {
+ protected boolean isActive() {
return isActive;
}
@Implementation
- public int getId() {
+ protected int getId() {
return id;
}
@Implementation
- public void getBoundsInScreen(Rect outBounds) {
+ protected void getBoundsInScreen(Rect outBounds) {
if (boundsInScreen == null) {
outBounds.setEmpty();
} else {
@@ -212,7 +212,7 @@ public class ShadowAccessibilityWindowInfo {
}
@Implementation
- public int getLayer() {
+ protected int getLayer() {
return layer;
}
@@ -223,17 +223,17 @@ public class ShadowAccessibilityWindowInfo {
}
@Implementation
- public boolean isFocused() {
+ protected boolean isFocused() {
return isFocused;
}
@Implementation
- public boolean isAccessibilityFocused() {
+ protected boolean isAccessibilityFocused() {
return isAccessibilityFocused;
}
@Implementation
- public void recycle() {
+ protected void recycle() {
// This shadow does not track recycling of windows.
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccountManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccountManager.java
index 421307573..fa8b3b083 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccountManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAccountManager.java
@@ -53,26 +53,27 @@ public class ShadowAccountManager {
private boolean authenticationErrorOnNextResponse = false;
@Implementation
- public void __constructor__(Context context, IAccountManager service) {
+ protected void __constructor__(Context context, IAccountManager service) {
mainHandler = new Handler(context.getMainLooper());
}
/**
- * @deprecated This method will be removed in Robolectric 3.4 Use {@link AccountManager#get(Context)} instead.
+ * @deprecated This method will be removed in Robolectric 3.4 Use {@link
+ * AccountManager#get(Context)} instead.
*/
@Deprecated
@Implementation
- public static AccountManager get(Context context) {
+ protected static AccountManager get(Context context) {
return (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
}
@Implementation
- public Account[] getAccounts() {
+ protected Account[] getAccounts() {
return accounts.toArray(new Account[accounts.size()]);
}
@Implementation
- public Account[] getAccountsByType(String type) {
+ protected Account[] getAccountsByType(String type) {
if (type == null) {
return getAccounts();
}
@@ -88,7 +89,7 @@ public class ShadowAccountManager {
}
@Implementation
- public synchronized void setAuthToken(Account account, String tokenType, String authToken) {
+ protected synchronized void setAuthToken(Account account, String tokenType, String authToken) {
if(accounts.contains(account)) {
Map<String, String> tokenMap = authTokens.get(account);
if(tokenMap == null) {
@@ -100,7 +101,7 @@ public class ShadowAccountManager {
}
@Implementation
- public String peekAuthToken(Account account, String tokenType) {
+ protected String peekAuthToken(Account account, String tokenType) {
Map<String, String> tokenMap = authTokens.get(account);
if(tokenMap != null) {
return tokenMap.get(tokenType);
@@ -109,7 +110,7 @@ public class ShadowAccountManager {
}
@Implementation
- public boolean addAccountExplicitly(Account account, String password, Bundle userdata) {
+ protected boolean addAccountExplicitly(Account account, String password, Bundle userdata) {
if (account == null) {
throw new IllegalArgumentException("account is null");
}
@@ -137,8 +138,8 @@ public class ShadowAccountManager {
}
@Implementation
- public String blockingGetAuthToken(Account account, String authTokenType,
- boolean notifyAuthFailure) {
+ protected String blockingGetAuthToken(
+ Account account, String authTokenType, boolean notifyAuthFailure) {
if (account == null) {
throw new IllegalArgumentException("account is null");
}
@@ -154,13 +155,12 @@ public class ShadowAccountManager {
}
/**
- * The remove operation is posted to the given {@code handler}, and will be
- * executed according to the {@link IdleState} of the corresponding {@link org.robolectric.util.Scheduler}.
+ * The remove operation is posted to the given {@code handler}, and will be executed according to
+ * the {@link IdleState} of the corresponding {@link org.robolectric.util.Scheduler}.
*/
@Implementation
- public AccountManagerFuture<Boolean> removeAccount(final Account account,
- AccountManagerCallback<Boolean> callback,
- Handler handler) {
+ protected AccountManagerFuture<Boolean> removeAccount(
+ final Account account, AccountManagerCallback<Boolean> callback, Handler handler) {
if (account == null) {
throw new IllegalArgumentException("account is null");
}
@@ -176,7 +176,7 @@ public class ShadowAccountManager {
}
@Implementation(minSdk = LOLLIPOP_MR1)
- public boolean removeAccountExplicitly(Account account) {
+ protected boolean removeAccountExplicitly(Account account) {
passwords.remove(account);
userData.remove(account);
if (accounts.remove(account)) {
@@ -196,13 +196,13 @@ public class ShadowAccountManager {
}
@Implementation
- public AuthenticatorDescription[] getAuthenticatorTypes() {
+ protected AuthenticatorDescription[] getAuthenticatorTypes() {
return authenticators.values().toArray(new AuthenticatorDescription[authenticators.size()]);
}
@Implementation
- public void addOnAccountsUpdatedListener(final OnAccountsUpdateListener listener,
- Handler handler, boolean updateImmediately) {
+ protected void addOnAccountsUpdatedListener(
+ final OnAccountsUpdateListener listener, Handler handler, boolean updateImmediately) {
if (listeners.contains(listener)) {
return;
@@ -216,12 +216,12 @@ public class ShadowAccountManager {
}
@Implementation
- public void removeOnAccountsUpdatedListener(OnAccountsUpdateListener listener) {
+ protected void removeOnAccountsUpdatedListener(OnAccountsUpdateListener listener) {
listeners.remove(listener);
}
@Implementation
- public String getUserData(Account account, String key) {
+ protected String getUserData(Account account, String key) {
if (account == null) {
throw new IllegalArgumentException("account is null");
}
@@ -239,7 +239,7 @@ public class ShadowAccountManager {
}
@Implementation
- public void setUserData(Account account, String key, String value) {
+ protected void setUserData(Account account, String key, String value) {
if (account == null) {
throw new IllegalArgumentException("account is null");
}
@@ -258,7 +258,7 @@ public class ShadowAccountManager {
}
@Implementation
- public void setPassword (Account account, String password) {
+ protected void setPassword(Account account, String password) {
if (account == null) {
throw new IllegalArgumentException("account is null");
}
@@ -271,7 +271,7 @@ public class ShadowAccountManager {
}
@Implementation
- public String getPassword (Account account) {
+ protected String getPassword(Account account) {
if (account == null) {
throw new IllegalArgumentException("account is null");
}
@@ -284,7 +284,7 @@ public class ShadowAccountManager {
}
@Implementation
- public void invalidateAuthToken(final String accountType, final String authToken) {
+ protected void invalidateAuthToken(final String accountType, final String authToken) {
Account[] accountsByType = getAccountsByType(accountType);
for (Account account : accountsByType) {
Map<String, String> tokenMap = authTokens.get(account);
@@ -396,7 +396,14 @@ public class ShadowAccountManager {
}
@Implementation
- public AccountManagerFuture<Bundle> addAccount(final String accountType, String authTokenType, String[] requiredFeatures, Bundle addAccountOptions, Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
+ protected AccountManagerFuture<Bundle> addAccount(
+ final String accountType,
+ String authTokenType,
+ String[] requiredFeatures,
+ Bundle addAccountOptions,
+ Activity activity,
+ AccountManagerCallback<Bundle> callback,
+ Handler handler) {
addAccountOptionsList.add(addAccountOptions);
pendingAddFuture = new RoboAccountManagerFuture(callback, handler, accountType, activity);
return pendingAddFuture;
@@ -431,37 +438,33 @@ public class ShadowAccountManager {
previousNames.put(account, previousName);
}
- /**
- * @see #setPreviousAccountName(Account, String)
- */
+ /** @see #setPreviousAccountName(Account, String) */
@Implementation(minSdk = LOLLIPOP)
- public String getPreviousName(Account account) {
+ protected String getPreviousName(Account account) {
return previousNames.get(account);
}
@Implementation
- public AccountManagerFuture<Bundle> getAuthToken(
- final Account account, final String authTokenType, final Bundle options,
- final Activity activity, final AccountManagerCallback<Bundle> callback, Handler handler) {
+ protected AccountManagerFuture<Bundle> getAuthToken(
+ final Account account,
+ final String authTokenType,
+ final Bundle options,
+ final Activity activity,
+ final AccountManagerCallback<Bundle> callback,
+ Handler handler) {
return start(
new BaseRoboAccountManagerFuture<Bundle>(callback, handler) {
@Override
public Bundle doWork()
throws OperationCanceledException, IOException, AuthenticatorException {
- Bundle result = new Bundle();
-
- String authToken = blockingGetAuthToken(account, authTokenType, false);
- result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
- result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
- result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
- return result;
+ return getAuthToken(account, authTokenType);
}
});
}
@Implementation
- public AccountManagerFuture<Bundle> getAuthToken(
+ protected AccountManagerFuture<Bundle> getAuthToken(
final Account account,
final String authTokenType,
final Bundle options,
@@ -471,22 +474,42 @@ public class ShadowAccountManager {
return start(new BaseRoboAccountManagerFuture<Bundle>(callback, handler) {
@Override
- public Bundle doWork() throws OperationCanceledException, IOException, AuthenticatorException {
- Bundle result = new Bundle();
-
- String authToken = blockingGetAuthToken(account, authTokenType, false);
- result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
- result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
- result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
- return result;
+ public Bundle doWork()
+ throws OperationCanceledException, IOException, AuthenticatorException {
+ return getAuthToken(account, authTokenType);
}
});
}
+ private Bundle getAuthToken(Account account, String authTokenType)
+ throws OperationCanceledException, IOException, AuthenticatorException {
+ Bundle result = new Bundle();
+
+ String authToken = blockingGetAuthToken(account, authTokenType, false);
+ result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
+ result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
+ result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
+
+ if (authToken != null) {
+ return result;
+ }
+
+ if (!authenticators.containsKey(account.type)) {
+ throw new AuthenticatorException("No authenticator specified for " + account.type);
+ }
+
+ Intent resultIntent = new Intent();
+ result.putParcelable(AccountManager.KEY_INTENT, resultIntent);
+
+ return result;
+ }
+
@Implementation
- public AccountManagerFuture<Boolean> hasFeatures(final Account account,
+ protected AccountManagerFuture<Boolean> hasFeatures(
+ final Account account,
final String[] features,
- AccountManagerCallback<Boolean> callback, Handler handler) {
+ AccountManagerCallback<Boolean> callback,
+ Handler handler) {
return start(new BaseRoboAccountManagerFuture<Boolean>(callback, handler) {
@Override
public Boolean doWork() throws OperationCanceledException, IOException, AuthenticatorException {
@@ -502,9 +525,11 @@ public class ShadowAccountManager {
}
@Implementation
- public AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures(
- final String type, final String[] features,
- AccountManagerCallback<Account[]> callback, Handler handler) {
+ protected AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures(
+ final String type,
+ final String[] features,
+ AccountManagerCallback<Account[]> callback,
+ Handler handler) {
return start(
new BaseRoboAccountManagerFuture<Account[]>(callback, handler) {
@Override
@@ -536,7 +561,7 @@ public class ShadowAccountManager {
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public Account[] getAccountsByTypeForPackage (String type, String packageName) {
+ protected Account[] getAccountsByTypeForPackage(String type, String packageName) {
List<Account> result = new ArrayList<>();
Account[] accountsByType = getAccountsByType(type);
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivity.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivity.java
index bf0c63109..3ca91c8b1 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivity.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivity.java
@@ -231,12 +231,12 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public ComponentName getCallingActivity() {
+ protected ComponentName getCallingActivity() {
return callingActivity;
}
@Implementation
- public void setDefaultKeyMode(int keyMode) {
+ protected void setDefaultKeyMode(int keyMode) {
mDefaultKeyMode = keyMode;
// Some modes use a SpannableStringBuilder to track & dispatch input events
@@ -262,23 +262,23 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public final void setResult(int resultCode) {
+ protected final void setResult(int resultCode) {
this.resultCode = resultCode;
}
@Implementation
- public final void setResult(int resultCode, Intent data) {
+ protected final void setResult(int resultCode, Intent data) {
this.resultCode = resultCode;
this.resultIntent = data;
}
@Implementation
- public LayoutInflater getLayoutInflater() {
+ protected LayoutInflater getLayoutInflater() {
return LayoutInflater.from(realActivity);
}
@Implementation
- public MenuInflater getMenuInflater() {
+ protected MenuInflater getMenuInflater() {
return new MenuInflater(realActivity);
}
@@ -290,12 +290,12 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
* @throws RuntimeException if the {@code contentView} has not been called first
*/
@Implementation
- public View findViewById(int id) {
+ protected View findViewById(int id) {
return getWindow().findViewById(id);
}
@Implementation
- public final Activity getParent() {
+ protected final Activity getParent() {
return parent;
}
@@ -310,24 +310,24 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public void onBackPressed() {
+ protected void onBackPressed() {
finish();
}
@Implementation
- public void finish() {
+ protected void finish() {
// Sets the mFinished field in the real activity so NoDisplay activities can be tested.
ReflectionHelpers.setField(Activity.class, realActivity, "mFinished", true);
}
@Implementation(minSdk = LOLLIPOP)
- public void finishAndRemoveTask() {
+ protected void finishAndRemoveTask() {
// Sets the mFinished field in the real activity so NoDisplay activities can be tested.
ReflectionHelpers.setField(Activity.class, realActivity, "mFinished", true);
}
@Implementation(minSdk = JELLY_BEAN)
- public void finishAffinity() {
+ protected void finishAffinity() {
// Sets the mFinished field in the real activity so NoDisplay activities can be tested.
ReflectionHelpers.setField(Activity.class, realActivity, "mFinished", true);
}
@@ -347,13 +347,13 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
/**
- * Constructs a new Window (a {@link com.android.internal.policy.impl.PhoneWindow}) if no window has previously been
- * set.
+ * Constructs a new Window (a {@link com.android.internal.policy.impl.PhoneWindow}) if no window
+ * has previously been set.
*
* @return the window associated with this Activity
*/
@Implementation
- public Window getWindow() {
+ protected Window getWindow() {
Window window = directlyOn(realActivity, Activity.class).getWindow();
if (window == null) {
@@ -373,12 +373,12 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public void runOnUiThread(Runnable action) {
+ protected void runOnUiThread(Runnable action) {
ShadowApplication.getInstance().getForegroundThreadScheduler().post(action);
}
@Implementation
- public void setRequestedOrientation(int requestedOrientation) {
+ protected void setRequestedOrientation(int requestedOrientation) {
if (getParent() != null) {
getParent().setRequestedOrientation(requestedOrientation);
} else {
@@ -387,7 +387,7 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public int getRequestedOrientation() {
+ protected int getRequestedOrientation() {
if (getParent() != null) {
return getParent().getRequestedOrientation();
} else {
@@ -396,7 +396,7 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public int getTaskId() {
+ protected int getTaskId() {
return 0;
}
@@ -448,7 +448,7 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public Object getLastNonConfigurationInstance() {
+ protected Object getLastNonConfigurationInstance() {
return lastNonConfigurationInstance;
}
@@ -464,7 +464,7 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public View getCurrentFocus() {
+ protected View getCurrentFocus() {
return currentFocus;
}
@@ -477,7 +477,7 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public boolean onCreateOptionsMenu(Menu menu) {
+ protected boolean onCreateOptionsMenu(Menu menu) {
optionsMenu = menu;
return directlyOn(realActivity, Activity.class).onCreateOptionsMenu(menu);
}
@@ -498,12 +498,6 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
* @return True if the click was handled, false otherwise.
*/
public boolean clickMenuItem(int menuItemResId) {
- if (optionsMenu == null) {
- throw new RuntimeException(
- "Activity does not have an options menu! Did you forget to call " +
- "super.onCreateOptionsMenu(menu) in " + realActivity.getClass().getName() + "?");
- }
-
final RoboMenuItem item = new RoboMenuItem(menuItemResId);
return realActivity.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item);
}
@@ -541,12 +535,12 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public final void showDialog(int id) {
+ protected final void showDialog(int id) {
showDialog(id, null);
}
@Implementation
- public final void dismissDialog(int id) {
+ protected final void dismissDialog(int id) {
final Dialog dialog = dialogForId.get(id);
if (dialog == null) {
throw new IllegalArgumentException();
@@ -556,12 +550,12 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public final void removeDialog(int id) {
+ protected final void removeDialog(int id) {
dialogForId.remove(id);
}
@Implementation
- public final boolean showDialog(int id, Bundle bundle) {
+ protected final boolean showDialog(int id, Bundle bundle) {
this.lastShownDialogId = id;
Dialog dialog = dialogForId.get(id);
@@ -589,7 +583,7 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public final boolean isTaskRoot() {
+ protected final boolean isTaskRoot() {
return mIsTaskRoot;
}
@@ -606,7 +600,7 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public void overridePendingTransition(int enterAnim, int exitAnim) {
+ protected void overridePendingTransition(int enterAnim, int exitAnim) {
pendingTransitionEnterAnimResId = enterAnim;
pendingTransitionExitAnimResId = exitAnim;
}
@@ -616,7 +610,7 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public void recreate() {
+ protected void recreate() {
Bundle outState = new Bundle();
final ActivityInvoker invoker = new ActivityInvoker();
@@ -635,12 +629,12 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public void startManagingCursor(Cursor c) {
+ protected void startManagingCursor(Cursor c) {
managedCursors.add(c);
}
@Implementation
- public void stopManagingCursor(Cursor c) {
+ protected void stopManagingCursor(Cursor c) {
managedCursors.remove(c);
}
@@ -649,19 +643,17 @@ public class ShadowActivity extends ShadowContextThemeWrapper {
}
@Implementation
- public final void setVolumeControlStream(int streamType) {
+ protected final void setVolumeControlStream(int streamType) {
this.streamType = streamType;
}
@Implementation
- public final int getVolumeControlStream() {
+ protected final int getVolumeControlStream() {
return streamType;
}
-
@Implementation(minSdk = M)
- public final void requestPermissions(String[] permissions, int requestCode) {
- }
+ protected final void requestPermissions(String[] permissions, int requestCode) {}
/**
* Starts a lock task.
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityGroup.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityGroup.java
index 0e47b1331..49ef26d15 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityGroup.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityGroup.java
@@ -10,7 +10,7 @@ public class ShadowActivityGroup extends ShadowActivity {
private Activity currentActivity;
@Implementation
- public android.app.Activity getCurrentActivity() {
+ protected android.app.Activity getCurrentActivity() {
return currentActivity;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityManager.java
index 75df60bb5..7a0163f81 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityManager.java
@@ -42,17 +42,17 @@ public class ShadowActivityManager {
}
@Implementation
- public int getMemoryClass() {
+ protected int getMemoryClass() {
return memoryClass;
}
@Implementation
- public static boolean isUserAMonkey() {
+ protected static boolean isUserAMonkey() {
return false;
}
@Implementation
- public List<ActivityManager.RunningTaskInfo> getRunningTasks(int maxNum) {
+ protected List<ActivityManager.RunningTaskInfo> getRunningTasks(int maxNum) {
return tasks;
}
@@ -69,12 +69,12 @@ public class ShadowActivityManager {
}
@Implementation
- public List<ActivityManager.RunningServiceInfo> getRunningServices(int maxNum) {
+ protected List<ActivityManager.RunningServiceInfo> getRunningServices(int maxNum) {
return services;
}
@Implementation
- public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
+ protected List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
// This method is explicitly documented not to return an empty list
if (processes.isEmpty()) {
return null;
@@ -105,12 +105,12 @@ public class ShadowActivityManager {
}
@Implementation
- public void killBackgroundProcesses(String packageName) {
+ protected void killBackgroundProcesses(String packageName) {
backgroundPackage = packageName;
}
@Implementation
- public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
+ protected void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
if (memoryInfo != null) {
outInfo.availMem = memoryInfo.availMem;
outInfo.lowMemory = memoryInfo.lowMemory;
@@ -120,7 +120,7 @@ public class ShadowActivityManager {
}
@Implementation
- public android.content.pm.ConfigurationInfo getDeviceConfigurationInfo() {
+ protected android.content.pm.ConfigurationInfo getDeviceConfigurationInfo() {
return new ConfigurationInfo();
}
@@ -181,12 +181,12 @@ public class ShadowActivityManager {
}
@Implementation(minSdk = O)
- public static IActivityManager getService() {
+ protected static IActivityManager getService() {
return ReflectionHelpers.createNullProxy(IActivityManager.class);
}
@Implementation(minSdk = KITKAT)
- public boolean isLowRamDevice() {
+ protected boolean isLowRamDevice() {
if (isLowRamDeviceOverride != null) {
return isLowRamDeviceOverride;
}
@@ -196,9 +196,8 @@ public class ShadowActivityManager {
/**
* Override the return value of isLowRamDevice().
*/
- public ShadowActivityManager setIsLowRamDevice(boolean isLowRamDevice) {
+ public void setIsLowRamDevice(boolean isLowRamDevice) {
isLowRamDeviceOverride = isLowRamDevice;
- return this;
}
@Implementation(minSdk = VERSION_CODES.M)
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityThread.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityThread.java
index 6723115f4..65dbc15ff 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityThread.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityThread.java
@@ -12,7 +12,7 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
-@Implements(value = ActivityThread.class, isInAndroidSdk = false)
+@Implements(value = ActivityThread.class, isInAndroidSdk = false, looseSignatures = true)
public class ShadowActivityThread {
private static ApplicationInfo applicationInfo;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAdapterView.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAdapterView.java
index 928e021b4..05a5ea0ff 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAdapterView.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAdapterView.java
@@ -23,7 +23,8 @@ public class ShadowAdapterView<T extends Adapter> extends ShadowViewGroup {
private AdapterView.OnItemSelectedListener itemSelectedListener;
@Implementation
- public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener itemSelectedListener) {
+ protected void setOnItemSelectedListener(
+ AdapterView.OnItemSelectedListener itemSelectedListener) {
this.itemSelectedListener = itemSelectedListener;
directlyOn(realAdapterView, AdapterView.class, "setOnItemSelectedListener", ClassParameter.from(AdapterView.OnItemSelectedListener.class, itemSelectedListener));
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlarmManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlarmManager.java
index e93fd2f1a..bea306d2e 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlarmManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlarmManager.java
@@ -39,7 +39,7 @@ public class ShadowAlarmManager {
}
@Implementation
- public void setTimeZone(String timeZone) {
+ protected void setTimeZone(String timeZone) {
// Do the real check first
Shadow.directlyOn(realObject, AlarmManager.class).setTimeZone(timeZone);
// Then do the right side effect
@@ -47,7 +47,7 @@ public class ShadowAlarmManager {
}
@Implementation
- public void set(int type, long triggerAtTime, PendingIntent operation) {
+ protected void set(int type, long triggerAtTime, PendingIntent operation) {
internalSet(type, triggerAtTime, 0L, operation, null);
}
@@ -58,7 +58,7 @@ public class ShadowAlarmManager {
}
@Implementation(minSdk = KITKAT)
- public void setExact(int type, long triggerAtTime, PendingIntent operation) {
+ protected void setExact(int type, long triggerAtTime, PendingIntent operation) {
internalSet(type, triggerAtTime, 0L, operation, null);
}
@@ -69,8 +69,8 @@ public class ShadowAlarmManager {
}
@Implementation(minSdk = KITKAT)
- public void setWindow(int type, long windowStartMillis, long windowLengthMillis,
- PendingIntent operation) {
+ protected void setWindow(
+ int type, long windowStartMillis, long windowLengthMillis, PendingIntent operation) {
internalSet(type, windowStartMillis, 0L, operation, null);
}
@@ -86,33 +86,34 @@ public class ShadowAlarmManager {
}
@Implementation(minSdk = M)
- public void setAndAllowWhileIdle(int type, long triggerAtTime, PendingIntent operation) {
+ protected void setAndAllowWhileIdle(int type, long triggerAtTime, PendingIntent operation) {
internalSet(type, triggerAtTime, 0L, operation, null);
}
@Implementation(minSdk = M)
- public void setExactAndAllowWhileIdle(int type, long triggerAtTime, PendingIntent operation) {
+ protected void setExactAndAllowWhileIdle(int type, long triggerAtTime, PendingIntent operation) {
internalSet(type, triggerAtTime, 0L, operation, null);
}
@Implementation
- public void setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation) {
+ protected void setRepeating(
+ int type, long triggerAtTime, long interval, PendingIntent operation) {
internalSet(type, triggerAtTime, interval, operation, null);
}
@Implementation
- public void setInexactRepeating(int type, long triggerAtMillis, long intervalMillis,
- PendingIntent operation) {
+ protected void setInexactRepeating(
+ int type, long triggerAtMillis, long intervalMillis, PendingIntent operation) {
internalSet(type, triggerAtMillis, intervalMillis, operation, null);
}
@Implementation(minSdk = LOLLIPOP)
- public void setAlarmClock(AlarmClockInfo info, PendingIntent operation) {
+ protected void setAlarmClock(AlarmClockInfo info, PendingIntent operation) {
internalSet(RTC_WAKEUP, info.getTriggerTime(), 0L, operation, info.getShowIntent());
}
@Implementation(minSdk = LOLLIPOP)
- public AlarmClockInfo getNextAlarmClock() {
+ protected AlarmClockInfo getNextAlarmClock() {
for (ScheduledAlarm scheduledAlarm : scheduledAlarms) {
AlarmClockInfo alarmClockInfo = scheduledAlarm.getAlarmClockInfo();
if (alarmClockInfo != null) {
@@ -166,7 +167,7 @@ public class ShadowAlarmManager {
}
@Implementation
- public void cancel(PendingIntent operation) {
+ protected void cancel(PendingIntent operation) {
ShadowPendingIntent shadowPendingIntent = Shadow.extract(operation);
final Intent toRemove = shadowPendingIntent.getSavedIntent();
final int requestCode = shadowPendingIntent.getRequestCode();
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlertDialog.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlertDialog.java
index 1db763025..deace5bfe 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlertDialog.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAlertDialog.java
@@ -96,22 +96,29 @@ public class ShadowAlertDialog extends ShadowDialog {
}
/**
- * @return return the view set with {@link AlertDialog.Builder#setView(View)}
+ * @return the view set with {@link AlertDialog.Builder#setView(View)}
*/
public View getView() {
return getShadowAlertController().getView();
}
/**
+ * @return the icon set with {@link AlertDialog.Builder#setIcon(int)}
+ */
+ public int getIconId() {
+ return getShadowAlertController().getIconId();
+ }
+
+ /**
* @return return the view set with {@link AlertDialog.Builder#setCustomTitle(View)}
*/
public View getCustomTitleView() {
return getShadowAlertController().getCustomTitleView();
}
- public ShadowAlertController getShadowAlertController() {
- AlertController alert = ReflectionHelpers.getField(realAlertDialog, "mAlert");
- return (ShadowAlertController) Shadow.extract(alert);
+ private ShadowAlertController getShadowAlertController() {
+ AlertController alertController = ReflectionHelpers.getField(realAlertDialog, "mAlert");
+ return (ShadowAlertController) Shadow.extract(alertController);
}
@Implements(AlertDialog.Builder.class)
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAnimationUtils.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAnimationUtils.java
index cc3bbdac8..8666c6b8e 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAnimationUtils.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAnimationUtils.java
@@ -16,12 +16,12 @@ import org.robolectric.shadow.api.Shadow;
public class ShadowAnimationUtils {
@Implementation
- public static Interpolator loadInterpolator(Context context, int id) {
+ protected static Interpolator loadInterpolator(Context context, int id) {
return new LinearInterpolator();
}
@Implementation
- public static LayoutAnimationController loadLayoutAnimation(Context context, int id) {
+ protected static LayoutAnimationController loadLayoutAnimation(Context context, int id) {
Animation anim = new TranslateAnimation(0, 0, 30, 0);
LayoutAnimationController layoutAnim = new LayoutAnimationController(anim);
ShadowLayoutAnimationController shadowLayoutAnimationController = Shadow.extract(layoutAnim);
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowApkAssets.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowApkAssets.java
index 12d8ad04c..c7177518d 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowApkAssets.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowApkAssets.java
@@ -1,7 +1,7 @@
package org.robolectric.shadows;
// transliterated from
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/core/jni/android_content_res_ApkAssets.cpp
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/core/jni/android_content_res_ApkAssets.cpp
abstract public class ShadowApkAssets {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppOpsManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppOpsManager.java
index c83d4ba57..959ccd751 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppOpsManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppOpsManager.java
@@ -1,33 +1,50 @@
package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.KITKAT;
+import static android.os.Build.VERSION_CODES.LOLLIPOP;
+import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.P;
+// BEGIN-INTERNAL
+import static android.os.Build.VERSION_CODES.Q;
+// END-INTERNAL
+import static org.robolectric.shadow.api.Shadow.invokeConstructor;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.app.AppOpsManager;
+import android.app.AppOpsManager.OnOpChangedListener;
import android.app.AppOpsManager.OpEntry;
import android.app.AppOpsManager.PackageOps;
+import android.content.Context;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.media.AudioAttributes.AttributeUsage;
+import android.os.Binder;
import android.os.Build;
+import com.android.internal.app.IAppOpsService;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.shadow.api.Shadow;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.ReflectionHelpers.ClassParameter;
-/**
- * Shadow for the {@link AppOpsManager}.
- */
@Implements(value = AppOpsManager.class)
public class ShadowAppOpsManager {
@@ -38,11 +55,31 @@ public class ShadowAppOpsManager {
private static final int PROXY_UID = 0;
private static final String PROXY_PACKAGE = "";
+ @RealObject private AppOpsManager realObject;
+
// Recorded operations, keyed by "uid|packageName"
private Multimap<String, Integer> mStoredOps = HashMultimap.create();
// "uid|packageName|opCode" => opMode
private Map<String, Integer> appModeMap = new HashMap<>();
+ // "packageName|opCode" => listener
+ private BiMap<String, OnOpChangedListener> appOpListeners = HashBiMap.create();
+
+ // op | (usage << 8) => ModeAndExcpetion
+ private Map<Integer, ModeAndException> audioRestrictions = new HashMap<>();
+
+ private Context context;
+
+ @Implementation(minSdk = KITKAT)
+ protected void __constructor__(Context context, IAppOpsService service) {
+ this.context = context;
+ invokeConstructor(
+ AppOpsManager.class,
+ realObject,
+ ClassParameter.from(Context.class, context),
+ ClassParameter.from(IAppOpsService.class, service));
+ }
+
/**
* Change the operating mode for the given op in the given app package. You must pass in both the
* uid and name of the application whose mode is being modified; if these do not match, the
@@ -50,7 +87,7 @@ public class ShadowAppOpsManager {
*
* <p>This method is public for testing {@link #checkOpNoThrow}. If {@link #checkOpNoThrow} is
* called afterwards with the {@code op}, {@code ui}, and {@code packageName} provided, it will
- * return the {@code mode} set here.
+ * return the {@code mode} set here.
*
* @param op The operation to modify. One of the OPSTR_* constants.
* @param uid The user id of the application whose mode will be changed.
@@ -64,14 +101,31 @@ public class ShadowAppOpsManager {
setMode(AppOpsManager.strOpToOp(op), uid, packageName, mode);
}
- /** Int version of {@link #setMode(String, int, String, int)}. Used by system internally. */
+ /**
+ * Int version of {@link #setMode(String, int, String, int)}.
+ *
+ * <p>This method is public for testing {@link #checkOpNoThrow}. If {@link #checkOpNoThrow} is *
+ * called afterwards with the {@code op}, {@code ui}, and {@code packageName} provided, it will *
+ * return the {@code mode} set here.
+ */
@Implementation(minSdk = KITKAT)
@HiddenApi
@RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
- protected void setMode(int op, int uid, String packageName, int mode) {
- appModeMap.put(getOpMapKey(uid, packageName, op), mode);
+ public void setMode(int op, int uid, String packageName, int mode) {
+ Integer oldMode = appModeMap.put(getOpMapKey(uid, packageName, op), mode);
+ OnOpChangedListener listener = appOpListeners.get(getListenerKey(op, packageName));
+ if (listener != null && !Objects.equals(oldMode, mode)) {
+ String[] sOpToString = ReflectionHelpers.getStaticField(AppOpsManager.class, "sOpToString");
+ listener.onOpChanged(sOpToString[op], packageName);
+ }
}
+ // BEGIN-INTERNAL
+ @Implementation(minSdk = Q)
+ public int unsafeCheckOpNoThrow(String op, int uid, String packageName) {
+ return checkOpNoThrow(AppOpsManager.strOpToOp(op), uid, packageName);
+ }
+ // END-INTERNAL
@Implementation(minSdk = P)
@Deprecated // renamed to unsafeCheckOpNoThrow
@@ -82,10 +136,12 @@ public class ShadowAppOpsManager {
/**
* Like {@link AppOpsManager#checkOp} but instead of throwing a {@link SecurityException} it
* returns {@link AppOpsManager#MODE_ERRORED}.
+ *
+ * <p>Made public for testing {@link #setMode} as the method is {@coe @hide}.
*/
@Implementation(minSdk = KITKAT)
@HiddenApi
- protected int checkOpNoThrow(int op, int uid, String packageName) {
+ public int checkOpNoThrow(int op, int uid, String packageName) {
Integer mode = appModeMap.get(getOpMapKey(uid, packageName, op));
if (mode == null) {
return AppOpsManager.MODE_ALLOWED;
@@ -101,6 +157,13 @@ public class ShadowAppOpsManager {
return AppOpsManager.MODE_ALLOWED;
}
+ @Implementation(minSdk = M)
+ @HiddenApi
+ protected int noteProxyOpNoThrow(int op, String proxiedPackageName) {
+ mStoredOps.put(getInternalKey(Binder.getCallingUid(), proxiedPackageName), op);
+ return checkOpNoThrow(op, Binder.getCallingUid(), proxiedPackageName);
+ }
+
@Implementation(minSdk = KITKAT)
@HiddenApi
public List<PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
@@ -121,6 +184,54 @@ public class ShadowAppOpsManager {
return ImmutableList.of(new PackageOps(packageName, uid, opEntries));
}
+ @Implementation(minSdk = KITKAT)
+ protected void checkPackage(int uid, String packageName) {
+ try {
+ // getPackageUid was introduced in API 24, so we call it on the shadow class
+ ShadowApplicationPackageManager shadowApplicationPackageManager =
+ Shadow.extract(context.getPackageManager());
+ int packageUid = shadowApplicationPackageManager.getPackageUid(packageName, 0);
+ if (packageUid == uid) {
+ return;
+ }
+ throw new SecurityException("Package " + packageName + " belongs to " + packageUid);
+ } catch (NameNotFoundException e) {
+ throw new SecurityException("Package " + packageName + " doesn't belong to " + uid, e);
+ }
+ }
+
+ /**
+ * Sets audio restrictions.
+ *
+ * <p>This method is public for testing, as the original method is {@code @hide}.
+ */
+ @Implementation(minSdk = LOLLIPOP)
+ @HiddenApi
+ public void setRestriction(
+ int code, @AttributeUsage int usage, int mode, String[] exceptionPackages) {
+ audioRestrictions.put(
+ getAudioRestrictionKey(code, usage), new ModeAndException(mode, exceptionPackages));
+ }
+
+ @Nullable
+ public ModeAndException getRestriction(int code, @AttributeUsage int usage) {
+ // this gives us room for 256 op_codes. There are 78 as of P.
+ return audioRestrictions.get(getAudioRestrictionKey(code, usage));
+ }
+
+ @Implementation(minSdk = KITKAT)
+ @HiddenApi
+ @RequiresPermission(value = android.Manifest.permission.WATCH_APPOPS)
+ protected void startWatchingMode(int op, String packageName, OnOpChangedListener callback) {
+ appOpListeners.put(getListenerKey(op, packageName), callback);
+ }
+
+ @Implementation(minSdk = KITKAT)
+ @RequiresPermission(value = android.Manifest.permission.WATCH_APPOPS)
+ protected void stopWatchingMode(OnOpChangedListener callback) {
+ appOpListeners.inverse().remove(callback);
+ }
+
private static OpEntry toOpEntry(Integer op) {
if (RuntimeEnvironment.getApiLevel() < Build.VERSION_CODES.M) {
return ReflectionHelpers.callConstructor(
@@ -143,4 +254,26 @@ public class ShadowAppOpsManager {
private static String getOpMapKey(int uid, String packageName, int opInt) {
return String.format("%s|%s|%s", uid, packageName, opInt);
}
+
+ private static int getAudioRestrictionKey(int code, @AttributeUsage int usage) {
+ return code | (usage << 8);
+ }
+
+ private static String getListenerKey(int op, String packageName) {
+ return String.format("%s|%s", op, packageName);
+ }
+
+ /** Class holding usage mode and excpetion packages. */
+ public static class ModeAndException {
+ public final int mode;
+ public final List<String> exceptionPackages;
+
+ public ModeAndException(int mode, String[] exceptionPackages) {
+ this.mode = mode;
+ this.exceptionPackages =
+ exceptionPackages == null
+ ? Collections.emptyList()
+ : Collections.unmodifiableList(Arrays.asList(exceptionPackages));
+ }
+ }
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetHost.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetHost.java
index 45c7ac5b8..2021ca5fa 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetHost.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetHost.java
@@ -19,7 +19,7 @@ public class ShadowAppWidgetHost {
private int appWidgetIdToAllocate;
@Implementation
- public void __constructor__(Context context, int hostId) {
+ protected void __constructor__(Context context, int hostId) {
this.context = context;
this.hostId = hostId;
}
@@ -37,13 +37,13 @@ public class ShadowAppWidgetHost {
}
@Implementation
- public int allocateAppWidgetId() {
+ protected int allocateAppWidgetId() {
return appWidgetIdToAllocate;
}
@Implementation
- public AppWidgetHostView createView(Context context, int appWidgetId,
- AppWidgetProviderInfo appWidget) {
+ protected AppWidgetHostView createView(
+ Context context, int appWidgetId, AppWidgetProviderInfo appWidget) {
AppWidgetHostView hostView = new AppWidgetHostView(context);
hostView.setAppWidget(appWidgetId, appWidget);
ShadowAppWidgetHostView shadowAppWidgetHostView = Shadow.extract(hostView);
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetHostView.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetHostView.java
index 46196d607..90a1d9b45 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetHostView.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetHostView.java
@@ -14,18 +14,18 @@ public class ShadowAppWidgetHostView extends ShadowViewGroup {
private AppWidgetHost host;
@Implementation
- public void setAppWidget(int appWidgetId, AppWidgetProviderInfo info) {
+ protected void setAppWidget(int appWidgetId, AppWidgetProviderInfo info) {
this.appWidgetId = appWidgetId;
this.appWidgetInfo = info;
}
@Implementation
- public int getAppWidgetId() {
+ protected int getAppWidgetId() {
return appWidgetId;
}
@Implementation
- public AppWidgetProviderInfo getAppWidgetInfo() {
+ protected AppWidgetProviderInfo getAppWidgetInfo() {
return appWidgetInfo;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetManager.java
index f00a9ffa3..09e047c8f 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppWidgetManager.java
@@ -60,7 +60,6 @@ public class ShadowAppWidgetManager {
// todo: implement
}
-
/**
* Finds or creates an {@code AppWidgetManager} for the given {@code context}
*
@@ -68,12 +67,12 @@ public class ShadowAppWidgetManager {
* @return the {@code AppWidgetManager} associated with the given {@code context}
*/
@Implementation
- public static AppWidgetManager getInstance(Context context) {
+ protected static AppWidgetManager getInstance(Context context) {
return instances.getInstance(context);
}
@Implementation
- public void updateAppWidget(int[] appWidgetIds, RemoteViews views) {
+ protected void updateAppWidget(int[] appWidgetIds, RemoteViews views) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(appWidgetId, views);
}
@@ -83,10 +82,10 @@ public class ShadowAppWidgetManager {
* Simulates updating an {@code AppWidget} with a new set of views
*
* @param appWidgetId id of widget
- * @param views views to update
+ * @param views views to update
*/
@Implementation
- public void updateAppWidget(int appWidgetId, RemoteViews views) {
+ protected void updateAppWidget(int appWidgetId, RemoteViews views) {
WidgetInfo widgetInfo = widgetInfos.get(appWidgetId);
int layoutId = views.getLayoutId();
if (widgetInfo.layoutId != layoutId || alwaysRecreateViewsDuringUpdate) {
@@ -98,7 +97,7 @@ public class ShadowAppWidgetManager {
}
@Implementation
- public int[] getAppWidgetIds(ComponentName provider) {
+ protected int[] getAppWidgetIds(ComponentName provider) {
List<Integer> idList = new ArrayList<>();
for (int id : widgetInfos.keySet()) {
WidgetInfo widgetInfo = widgetInfos.get(id);
@@ -114,7 +113,7 @@ public class ShadowAppWidgetManager {
}
@Implementation
- public List<AppWidgetProviderInfo> getInstalledProviders() {
+ protected List<AppWidgetProviderInfo> getInstalledProviders() {
return new ArrayList<>(installedProviders);
}
@@ -134,7 +133,7 @@ public class ShadowAppWidgetManager {
}
@Implementation
- public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
+ protected AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
WidgetInfo widgetInfo = widgetInfos.get(appWidgetId);
if (widgetInfo == null) return null;
return widgetInfo.info;
@@ -152,7 +151,7 @@ public class ShadowAppWidgetManager {
}
@Implementation
- public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider) {
+ protected boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider) {
if (validWidgetProviderComponentName) {
bindAppWidgetId(appWidgetId, provider);
return allowedToBindWidgets;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowApplication.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowApplication.java
index 202709132..f2c10ac21 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowApplication.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowApplication.java
@@ -54,6 +54,12 @@ public class ShadowApplication extends ShadowContextWrapper {
private PopupWindow latestPopupWindow;
private ListPopupWindow latestListPopupWindow;
+ /**
+ * @deprecated Use
+ * `shadowOf({@link androidx.test.core.app.ApplicationProvider#getApplicationContext})`
+ * instead.
+ */
+ @Deprecated
public static ShadowApplication getInstance() {
return RuntimeEnvironment.application == null
? null
@@ -239,19 +245,27 @@ public class ShadowApplication extends ShadowContextWrapper {
return appWidgetManager;
}
+ /**
+ * @deprecated Use {@link ShadowAlertDialog#getLatestAlertDialog()} instead.
+ */
+ @Deprecated
public ShadowAlertDialog getLatestAlertDialog() {
return latestAlertDialog;
}
- public void setLatestAlertDialog(ShadowAlertDialog latestAlertDialog) {
+ protected void setLatestAlertDialog(ShadowAlertDialog latestAlertDialog) {
this.latestAlertDialog = latestAlertDialog;
}
+ /**
+ * @deprecated Use {@link ShadowDialog#getLatestDialog()} instead.
+ */
+ @Deprecated
public ShadowDialog getLatestDialog() {
return latestDialog;
}
- public void setLatestDialog(ShadowDialog latestDialog) {
+ protected void setLatestDialog(ShadowDialog latestDialog) {
this.latestDialog = latestDialog;
}
@@ -305,11 +319,15 @@ public class ShadowApplication extends ShadowContextWrapper {
shadowInstrumentation.checkActivities(checkActivities);
}
+ /**
+ * @deprecated Use {@link ShadowPopupMenu#getLatestPopupMenu()} instead.
+ */
+ @Deprecated
public ShadowPopupMenu getLatestPopupMenu() {
return latestPopupMenu;
}
- public void setLatestPopupMenu(ShadowPopupMenu latestPopupMenu) {
+ protected void setLatestPopupMenu(ShadowPopupMenu latestPopupMenu) {
this.latestPopupMenu = latestPopupMenu;
}
@@ -317,7 +335,7 @@ public class ShadowApplication extends ShadowContextWrapper {
return latestPopupWindow;
}
- public void setLatestPopupWindow(PopupWindow latestPopupWindow) {
+ protected void setLatestPopupWindow(PopupWindow latestPopupWindow) {
this.latestPopupWindow = latestPopupWindow;
}
@@ -325,7 +343,7 @@ public class ShadowApplication extends ShadowContextWrapper {
return latestListPopupWindow;
}
- public void setLatestListPopupWindow(ListPopupWindow latestListPopupWindow) {
+ protected void setLatestListPopupWindow(ListPopupWindow latestListPopupWindow) {
this.latestListPopupWindow = latestListPopupWindow;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowApplicationPackageManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowApplicationPackageManager.java
index e01cac01b..ff86a476b 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowApplicationPackageManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowApplicationPackageManager.java
@@ -5,6 +5,7 @@ import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.GET_META_DATA;
import static android.content.pm.PackageManager.GET_SIGNATURES;
+import static android.content.pm.PackageManager.MATCH_ALL;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
import static android.content.pm.PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
@@ -67,6 +68,8 @@ import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
import android.os.Handler;
import android.os.Looper;
import android.os.PersistableBundle;
@@ -95,7 +98,6 @@ import org.robolectric.annotation.RealObject;
@Implements(value = ApplicationPackageManager.class, isInAndroidSdk = false, looseSignatures = true)
public class ShadowApplicationPackageManager extends ShadowPackageManager {
-
/** Package name of the Android platform. */
private static final String PLATFORM_PACKAGE_NAME = "android";
@@ -105,9 +107,7 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
/** {@link Uri} scheme of installed apps. */
private static final String PACKAGE_SCHEME = "package";
-
- @RealObject
- private ApplicationPackageManager realObject;
+ @RealObject private ApplicationPackageManager realObject;
private Context context;
@@ -159,9 +159,7 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
for (ActivityInfo activity : packageInfo.activities) {
if (activityName.equals(activity.name)) {
ActivityInfo result = new ActivityInfo(activity);
- if ((flags & GET_META_DATA) != 0) {
- result.metaData = activity.metaData;
- }
+ applyFlagsToComponentInfo(result, flags);
return result;
}
@@ -216,9 +214,7 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
}
}
- return results.isEmpty()
- ? null
- :results.toArray(new String[results.size()]);
+ return results.isEmpty() ? null : results.toArray(new String[results.size()]);
}
@Implementation
@@ -241,17 +237,8 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
if (packageInfo != null && packageInfo.providers != null) {
for (ProviderInfo provider : packageInfo.providers) {
if (resolvePackageName(packageName, component).equals(provider.name)) {
- ProviderInfo result = new ProviderInfo();
- result.packageName = provider.packageName;
- result.name = provider.name;
- result.authority = provider.authority;
- result.readPermission = provider.readPermission;
- result.writePermission = provider.writePermission;
- result.pathPermissions = provider.pathPermissions;
-
- if ((flags & GET_META_DATA) != 0) {
- result.metaData = provider.metaData;
- }
+ ProviderInfo result = new ProviderInfo(provider);
+ applyFlagsToComponentInfo(result, flags);
return result;
}
}
@@ -331,28 +318,29 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
@Implementation
protected List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
- // Check the manually added resolve infos first.
+ List<ResolveInfo> result = new ArrayList<>();
List<ResolveInfo> resolveInfoList = queryOverriddenIntents(intent, flags);
if (!resolveInfoList.isEmpty()) {
- return filterResolvedComponent(
- resolveInfoList, flags, (resolveInfo) -> resolveInfo.serviceInfo);
+ result.addAll(
+ filterResolvedComponent(
+ resolveInfoList, flags, (resolveInfo) -> resolveInfo.serviceInfo));
}
if (isExplicitIntent(intent)) {
ResolveInfo resolvedService = resolveServiceForExplicitIntent(intent);
if (resolvedService != null) {
- resolveInfoList =
+ result.addAll(
filterResolvedComponent(
- Arrays.asList(resolvedService), flags, (resolveInfo) -> resolveInfo.serviceInfo);
+ Arrays.asList(resolvedService), flags, (resolveInfo) -> resolveInfo.serviceInfo));
}
} else {
- resolveInfoList =
+ result.addAll(
filterResolvedComponent(
queryImplicitIntentServices(intent, flags),
flags,
- (resolveInfo) -> resolveInfo.serviceInfo);
+ (resolveInfo) -> resolveInfo.serviceInfo));
}
- return resolveInfoList;
+ return result;
}
private List<ResolveInfo> filterResolvedComponent(
@@ -368,8 +356,18 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
for (Iterator<ResolveInfo> iterator = resolveInfoList.iterator(); iterator.hasNext(); ) {
ResolveInfo resolveInfo = iterator.next();
- ComponentInfo componentInfo =
- (resolveInfo == null) ? null : componentInfoFn.apply(resolveInfo);
+ ComponentInfo componentInfo = componentInfoFn.apply(resolveInfo);
+
+ boolean hasSomeComponentInfo =
+ resolveInfo.activityInfo != null
+ || resolveInfo.serviceInfo != null
+ || (VERSION.SDK_INT >= VERSION_CODES.KITKAT && resolveInfo.providerInfo != null);
+ if (componentInfo == null && hasSomeComponentInfo) {
+ // wrong type of component. For backward compatibility we keep those entries that doesn't
+ // have any component.
+ iterator.remove();
+ continue;
+ }
if (isFlagSet(flags, PackageManager.MATCH_SYSTEM_ONLY)) {
if (componentInfo == null || componentInfo.applicationInfo == null) {
@@ -458,9 +456,7 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
return queryIntentActivities(intent, flags);
}
- /**
- * Returns true if intent has specified a specific component.
- */
+ /** Returns true if intent has specified a specific component. */
private static boolean isExplicitIntent(Intent intent) {
return getComponentForIntent(intent) != null;
}
@@ -509,8 +505,8 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
return null;
}
- private static <T extends Component> T findMatchingComponent(ComponentName componentName,
- List<T> components) {
+ private static <T extends Component> T findMatchingComponent(
+ ComponentName componentName, List<T> components) {
for (T component : components) {
if (componentName.equals(component.getComponentName())) {
return component;
@@ -653,8 +649,8 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
return PackageManager.PERMISSION_GRANTED;
}
- if ((permissionsInfo.requestedPermissionsFlags[i]
- & REQUESTED_PERMISSION_GRANTED) == REQUESTED_PERMISSION_GRANTED) {
+ if ((permissionsInfo.requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED)
+ == REQUESTED_PERMISSION_GRANTED) {
return PackageManager.PERMISSION_GRANTED;
}
}
@@ -667,18 +663,16 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
* Returns whether a permission should be treated as granted to the package for backward
* compatibility reasons.
*
- * <p>
- * Before Robolectric 4.0 the ShadowPackageManager treated every requested permission as
+ * <p>Before Robolectric 4.0 the ShadowPackageManager treated every requested permission as
* automatically granted. 4.0 changes this behavior, and only treats a permission as granted if
- * PackageInfo.requestedPermissionFlags[permissionIndex] & REQUESTED_PERMISSION_GRANTED
- * == REQUESTED_PERMISSION_GRANTED
- * which matches the real PackageManager's behavior.
+ * PackageInfo.requestedPermissionFlags[permissionIndex] & REQUESTED_PERMISSION_GRANTED ==
+ * REQUESTED_PERMISSION_GRANTED which matches the real PackageManager's behavior.
*
- * <p>Since many existing tests didn't set the requestedPermissionFlags on their
- * {@code PackageInfo} objects, but assumed that all permissions are granted, we auto-grant
- * all permissions if the requestedPermissionFlags is not set.
- * If the requestedPermissionFlags is set, we assume that the test is configuring the
- * permission grant state, and we don't override this setting.
+ * <p>Since many existing tests didn't set the requestedPermissionFlags on their {@code
+ * PackageInfo} objects, but assumed that all permissions are granted, we auto-grant all
+ * permissions if the requestedPermissionFlags is not set. If the requestedPermissionFlags is set,
+ * we assume that the test is configuring the permission grant state, and we don't override this
+ * setting.
*/
private boolean isGrantedForBackwardsCompatibility(String pkgName, PackageInfo permissionsInfo) {
// Note: it might be cleaner to auto-grant these permissions when the package is added to the
@@ -701,12 +695,8 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
if (packageInfo != null && packageInfo.receivers != null) {
for (ActivityInfo receiver : packageInfo.receivers) {
if (resolvePackageName(packageName, className).equals(receiver.name)) {
- ActivityInfo result = new ActivityInfo();
- result.packageName = receiver.packageName;
- result.name = receiver.name;
- if ((flags & GET_META_DATA) != 0) {
- result.metaData = receiver.metaData;
- }
+ ActivityInfo result = new ActivityInfo(receiver);
+ applyFlagsToComponentInfo(result, flags);
return result;
}
}
@@ -717,28 +707,29 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
@Implementation
protected List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
- // Check the manually added resolve infos first.
+ List<ResolveInfo> result = new ArrayList<>();
List<ResolveInfo> resolveInfoList = queryOverriddenIntents(intent, flags);
if (!resolveInfoList.isEmpty()) {
- return filterResolvedComponent(
- resolveInfoList, flags, (resolveInfo) -> resolveInfo.activityInfo);
+ result.addAll(
+ filterResolvedComponent(
+ resolveInfoList, flags, (resolveInfo) -> resolveInfo.activityInfo));
}
if (isExplicitIntent(intent)) {
ResolveInfo resolvedReceiver = resolveReceiverForExplicitIntent(intent);
if (resolvedReceiver != null) {
- resolveInfoList =
+ result.addAll(
filterResolvedComponent(
- Arrays.asList(resolvedReceiver), flags, (resolveInfo) -> resolveInfo.activityInfo);
+ Arrays.asList(resolvedReceiver), flags, (resolveInfo) -> resolveInfo.activityInfo));
}
} else {
- resolveInfoList =
+ result.addAll(
filterResolvedComponent(
queryImplicitIntentReceivers(intent, flags),
flags,
- (resolveInfo) -> resolveInfo.activityInfo);
+ (resolveInfo) -> resolveInfo.activityInfo));
}
- return resolveInfoList;
+ return result;
}
private static IntentFilter matchIntentFilter(
@@ -775,13 +766,11 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
if (packageInfo.services != null) {
for (ServiceInfo service : packageInfo.services) {
if (serviceName.equals(service.name)) {
- ServiceInfo result = new ServiceInfo();
- result.packageName = service.packageName;
- result.name = service.name;
- result.applicationInfo = service.applicationInfo;
- result.permission = service.permission;
- if ((flags & GET_META_DATA) != 0) {
- result.metaData = service.metaData;
+ ServiceInfo result = new ServiceInfo(service);
+ applyFlagsToComponentInfo(result, flags);
+ result.applicationInfo = new ApplicationInfo(service.applicationInfo);
+ if (result.processName == null) {
+ result.processName = result.applicationInfo.processName;
}
return result;
}
@@ -792,6 +781,16 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
return null;
}
+ private void applyFlagsToComponentInfo(ComponentInfo result, int flags)
+ throws NameNotFoundException {
+ if ((flags & GET_META_DATA) == 0) {
+ result.metaData = null;
+ }
+ if ((flags & MATCH_ALL) != 0) {
+ return;
+ }
+ }
+
@Implementation
protected Resources getResourcesForApplication(@NonNull ApplicationInfo applicationInfo)
throws PackageManager.NameNotFoundException {
@@ -835,12 +834,16 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
@Implementation(minSdk = M)
protected boolean shouldShowRequestPermissionRationale(String permission) {
- return permissionRationaleMap.containsKey(permission) ? permissionRationaleMap.get(permission) : false;
+ return permissionRationaleMap.containsKey(permission)
+ ? permissionRationaleMap.get(permission)
+ : false;
}
@Implementation
protected FeatureInfo[] getSystemAvailableFeatures() {
- return systemAvailableFeatures.isEmpty() ? null : systemAvailableFeatures.toArray(new FeatureInfo[systemAvailableFeatures.size()]);
+ return systemAvailableFeatures.isEmpty()
+ ? null
+ : systemAvailableFeatures.toArray(new FeatureInfo[systemAvailableFeatures.size()]);
}
@Implementation
@@ -911,37 +914,46 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
@Implementation(maxSdk = JELLY_BEAN)
protected void getPackageSizeInfo(Object pkgName, Object observer) {
final PackageStats packageStats = packageStatsMap.get((String) pkgName);
- new Handler(Looper.getMainLooper()).post(() -> {
- try {
- ((IPackageStatsObserver) observer).onGetStatsCompleted(packageStats, packageStats != null);
- } catch (RemoteException remoteException) {
- remoteException.rethrowFromSystemServer();
- }
- });
+ new Handler(Looper.getMainLooper())
+ .post(
+ () -> {
+ try {
+ ((IPackageStatsObserver) observer)
+ .onGetStatsCompleted(packageStats, packageStats != null);
+ } catch (RemoteException remoteException) {
+ remoteException.rethrowFromSystemServer();
+ }
+ });
}
@Implementation(minSdk = JELLY_BEAN_MR1, maxSdk = M)
protected void getPackageSizeInfo(Object pkgName, Object uid, final Object observer) {
final PackageStats packageStats = packageStatsMap.get((String) pkgName);
- new Handler(Looper.getMainLooper()).post(() -> {
- try {
- ((IPackageStatsObserver) observer).onGetStatsCompleted(packageStats, packageStats != null);
- } catch (RemoteException remoteException) {
- remoteException.rethrowFromSystemServer();
- }
- });
+ new Handler(Looper.getMainLooper())
+ .post(
+ () -> {
+ try {
+ ((IPackageStatsObserver) observer)
+ .onGetStatsCompleted(packageStats, packageStats != null);
+ } catch (RemoteException remoteException) {
+ remoteException.rethrowFromSystemServer();
+ }
+ });
}
@Implementation(minSdk = N)
protected void getPackageSizeInfoAsUser(Object pkgName, Object uid, final Object observer) {
final PackageStats packageStats = packageStatsMap.get((String) pkgName);
- new Handler(Looper.getMainLooper()).post(() -> {
- try {
- ((IPackageStatsObserver) observer).onGetStatsCompleted(packageStats, packageStats != null);
- } catch (RemoteException remoteException) {
- remoteException.rethrowFromSystemServer();
- }
- });
+ new Handler(Looper.getMainLooper())
+ .post(
+ () -> {
+ try {
+ ((IPackageStatsObserver) observer)
+ .onGetStatsCompleted(packageStats, packageStats != null);
+ } catch (RemoteException remoteException) {
+ remoteException.rethrowFromSystemServer();
+ }
+ });
}
@Implementation
@@ -1098,9 +1110,7 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
return 0;
}
- /**
- * @see ShadowPackageManager#addPermissionGroupInfo(android.content.pm.PermissionGroupInfo)
- */
+ /** @see ShadowPackageManager#addPermissionGroupInfo(android.content.pm.PermissionGroupInfo) */
@Implementation
protected PermissionGroupInfo getPermissionGroupInfo(String name, int flags)
throws NameNotFoundException {
@@ -1119,9 +1129,7 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
throw new NameNotFoundException(name);
}
- /**
- * @see ShadowPackageManager#addPermissionGroupInfo(android.content.pm.PermissionGroupInfo)
- */
+ /** @see ShadowPackageManager#addPermissionGroupInfo(android.content.pm.PermissionGroupInfo) */
@Implementation
protected List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
ArrayList<PermissionGroupInfo> allPermissionGroups = new ArrayList<PermissionGroupInfo>();
@@ -1137,8 +1145,8 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
for (Package pkg : packages.values()) {
for (PermissionGroup permissionGroup : pkg.permissionGroups) {
if (!handledPermissionGroups.contains(permissionGroup.info.name)) {
- PermissionGroupInfo permissionGroupInfo = PackageParser
- .generatePermissionGroupInfo(permissionGroup, flags);
+ PermissionGroupInfo permissionGroupInfo =
+ PackageParser.generatePermissionGroupInfo(permissionGroup, flags);
allPermissionGroups.add(new PermissionGroupInfo(permissionGroupInfo));
handledPermissionGroups.add(permissionGroup.info.name);
}
@@ -1154,7 +1162,7 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
PackageInfo info = packageInfos.get(packageName);
if (info != null) {
try {
- PackageInfo packageInfo = getPackageInfo(packageName, -1);
+ getPackageInfo(packageName, -1);
} catch (NameNotFoundException e) {
throw new IllegalArgumentException(e);
}
@@ -1875,4 +1883,9 @@ public class ShadowApplicationPackageManager extends ShadowPackageManager {
}
return setting.isSuspended();
}
+
+ @Implementation(minSdk = O)
+ protected boolean isInstantApp(String packageName) {
+ return false;
+ }
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscApkAssets9.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscApkAssets9.java
index ee697f18d..aedfb5054 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscApkAssets9.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscApkAssets9.java
@@ -28,7 +28,7 @@ import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.ReflectionHelpers.ClassParameter;
// transliterated from
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/core/jni/android_content_res_ApkAssets.cpp
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/core/jni/android_content_res_ApkAssets.cpp
@Implements(value = ApkAssets.class, minSdk = Build.VERSION_CODES.P,
shadowPicker = Picker.class, isInAndroidSdk = false)
@@ -189,12 +189,12 @@ public class ShadowArscApkAssets9 extends ShadowApkAssets {
throws IOException {
throw new UnsupportedOperationException();
// return getFromCacheOrLoad(
- // new Key(fd, friendlyName, system, forceSharedLibrary, false),
- // () -> directlyOn(ApkAssets.class, "loadFromPath",
- // ClassParameter.from(FileDescriptor.class, fd),
- // ClassParameter.from(String.class, friendlyName),
- // ClassParameter.from(boolean.class, system),
- // ClassParameter.from(boolean.class, forceSharedLibrary)));
+ // new Key(fd, friendlyName, system, forceSharedLibrary, false),
+ // () -> directlyOn(ApkAssets.class, "loadFromPath",
+ // ClassParameter.from(FileDescriptor.class, fd),
+ // ClassParameter.from(String.class, friendlyName),
+ // ClassParameter.from(boolean.class, system),
+ // ClassParameter.from(boolean.class, forceSharedLibrary)));
}
// static jlong NativeLoad(JNIEnv* env, jclass /*clazz*/, jstring java_path, jboolean system,
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager.java
index 85c49aa8e..8c81f564e 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager.java
@@ -15,7 +15,6 @@ import static org.robolectric.res.android.Errors.BAD_INDEX;
import static org.robolectric.res.android.Errors.NO_ERROR;
import static org.robolectric.res.android.Util.ALOGV;
import static org.robolectric.res.android.Util.isTruthy;
-import static org.robolectric.shadow.api.Shadow.directlyOn;
import android.content.res.AssetManager;
import android.os.Build.VERSION_CODES;
@@ -67,7 +66,7 @@ import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowAssetManager.Picker;
import org.robolectric.util.ReflectionHelpers;
-// native method impls transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/core/jni/android_util_AssetManager.cpp
+// native method impls transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/core/jni/android_util_AssetManager.cpp
@Implements(value = AssetManager.class, maxSdk = VERSION_CODES.O_MR1,
shadowPicker = Picker.class)
public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
@@ -89,7 +88,7 @@ public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
}
@Implementation
- public final String[] list(String path) throws IOException {
+ protected final String[] list(String path) throws IOException {
CppAssetManager am = assetManagerForJavaObject();
String fileName8 = path;
@@ -190,7 +189,7 @@ public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
}
@Implementation
- public String getResourceName(int resid) {
+ protected String getResourceName(int resid) {
CppAssetManager am = assetManagerForJavaObject();
ResourceName name = new ResourceName();
@@ -220,7 +219,7 @@ public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
}
@Implementation
- public String getResourcePackageName(int resid) {
+ protected String getResourcePackageName(int resid) {
CppAssetManager cppAssetManager = assetManagerForJavaObject();
ResourceName name = new ResourceName();
@@ -232,7 +231,7 @@ public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
}
@Implementation
- public String getResourceTypeName(int resid) {
+ protected String getResourceTypeName(int resid) {
CppAssetManager cppAssetManager = assetManagerForJavaObject();
ResourceName name = new ResourceName();
@@ -244,7 +243,7 @@ public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
}
@Implementation
- public String getResourceEntryName(int resid) {
+ protected String getResourceEntryName(int resid) {
CppAssetManager cppAssetManager = assetManagerForJavaObject();
ResourceName name = new ResourceName();
@@ -522,29 +521,29 @@ public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
final Ref<Integer> typeSpecFlags = new Ref<>(null);
int block = res.getResource(ident, value, false, density, typeSpecFlags, config);
if (kThrowOnBadId) {
- if (block == BAD_INDEX) {
- throw new IllegalStateException("Bad resource!");
- //return 0;
- }
+ if (block == BAD_INDEX) {
+ throw new IllegalStateException("Bad resource!");
+ //return 0;
+ }
}
final Ref<Integer> ref = new Ref<>(ident);
if (resolve) {
- block = res.resolveReference(value, block, ref, typeSpecFlags, config);
- if (kThrowOnBadId) {
- if (block == BAD_INDEX) {
- throw new IllegalStateException("Bad resource!");
- //return 0;
- }
+ block = res.resolveReference(value, block, ref, typeSpecFlags, config);
+ if (kThrowOnBadId) {
+ if (block == BAD_INDEX) {
+ throw new IllegalStateException("Bad resource!");
+ //return 0;
}
+ }
}
if (block >= 0) {
- //return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config);
+ //return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config);
return copyValue(outValue, res, value.get(), ref.get(), block, typeSpecFlags.get(),
config.get());
}
return block;
-}
+ }
private static int copyValue(TypedValue outValue, ResTable table, Res_value value, int ref, int block,
int typeSpecFlags) {
@@ -671,7 +670,7 @@ public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
// /*package*/ static final int STYLE_DENSITY = 5;
-/* lowercase hexadecimal notation. */
+ /* lowercase hexadecimal notation. */
//# define PRIx8 "x"
// # define PRIx16 "x"
// # define PRIx32 "x"
@@ -904,7 +903,7 @@ public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
//printf("Resolving attribute reference\n");
final Ref<Res_value> resValueRef = new Ref<>(value);
int newBlock = res.resolveReference(resValueRef, block, resid,
- typeSetFlags, config);
+ typeSetFlags, config);
value = resValueRef.get();
if (kThrowOnBadId) {
if (newBlock == BAD_INDEX) {
@@ -955,7 +954,7 @@ public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
}
@Implementation
- public final SparseArray<String> getAssignedPackageIdentifiers() {
+ protected final SparseArray<String> getAssignedPackageIdentifiers() {
CppAssetManager am = assetManagerForJavaObject();
final ResTable res = am.getResources();
@@ -1116,10 +1115,10 @@ public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
}
}
if (valueRef.get().dataType == DataType.STRING.code()) {
- final ResStringPool pool = res.getTableStringBlock(block);
- str = pool.stringAt(valueRef.get().data);
+ final ResStringPool pool = res.getTableStringBlock(block);
+ str = pool.stringAt(valueRef.get().data);
- // assume we can skip utf8 vs utf 16 handling
+ // assume we can skip utf8 vs utf 16 handling
// final char* str8 = pool.string8At(value.data, &strLen);
// if (str8 != NULL) {
@@ -1247,9 +1246,9 @@ public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
@HiddenApi @Implementation(maxSdk = VERSION_CODES.KITKAT)
protected void init() {
- // if (isSystem) {
- // verifySystemIdmaps();
- // }
+ // if (isSystem) {
+ // verifySystemIdmaps();
+ // }
init(false);
}
@@ -1315,7 +1314,7 @@ public class ShadowArscAssetManager extends ShadowAssetManager.ArscBase {
return am.getResources().getTableCount();
}
-
+
synchronized private CppAssetManager assetManagerForJavaObject() {
if (cppAssetManager == null) {
throw new NullPointerException();
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager9.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager9.java
index 94074e032..edf8811b8 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager9.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager9.java
@@ -1,6 +1,6 @@
package org.robolectric.shadows;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/core/jni/android_util_AssetManager.cpp
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/core/jni/android_util_AssetManager.cpp
import static android.os.Build.VERSION_CODES.P;
import static android.os.Build.VERSION_CODES.Q;
@@ -494,7 +494,7 @@ public class ShadowArscAssetManager9 extends ShadowAssetManager.ArscBase {
return cppAssetManagerRef;
}
- // static void NativeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) {
+ // static void NativeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) {
@Implementation(minSdk = P)
protected static void nativeDestroy(long ptr) {
if (ptr == systemCppAssetManager2Ref) {
@@ -1164,7 +1164,7 @@ public class ShadowArscAssetManager9 extends ShadowAssetManager.ArscBase {
}
// if (name.type != null) {
- result.append(name.type/*, name.type_len*/);
+ result.append(name.type/*, name.type_len*/);
// } else {
// result.append( /*util.Utf16ToUtf8(StringPiece16(*/ name.type16 /*, name.type_len))*/);
// }
@@ -1176,7 +1176,7 @@ public class ShadowArscAssetManager9 extends ShadowAssetManager.ArscBase {
}
// if (name.entry != null) {
- result.append(name.entry/*, name.entry_len*/);
+ result.append(name.entry/*, name.entry_len*/);
// } else {
// result.append( /*util.Utf16ToUtf8(StringPiece16(*/ name.entry16 /*, name.entry_len)*/);
// }
@@ -1211,8 +1211,8 @@ public class ShadowArscAssetManager9 extends ShadowAssetManager.ArscBase {
if (name.type != null) {
return name.type;
- // } else if (name.get().type16 != null) {
- // return name.get().type16; // env.NewString(reinterpret_cast<jchar*>(name.type16), name.type_len);
+ // } else if (name.get().type16 != null) {
+ // return name.get().type16; // env.NewString(reinterpret_cast<jchar*>(name.type16), name.type_len);
}
return null;
}
@@ -1228,8 +1228,8 @@ public class ShadowArscAssetManager9 extends ShadowAssetManager.ArscBase {
if (name.entry != null) {
return name.entry;
- // } else if (name.entry16 != null) {
- // return name.entry16; // env.NewString(reinterpret_cast<jchar*>(name.entry16), name.entry_len);
+ // } else if (name.entry16 != null) {
+ // return name.entry16; // env.NewString(reinterpret_cast<jchar*>(name.entry16), name.entry_len);
}
return null;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAsyncTask.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAsyncTask.java
index 3710fe7aa..85700d40f 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAsyncTask.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAsyncTask.java
@@ -60,27 +60,28 @@ public class ShadowAsyncTask<Params, Progress, Result> {
}
@Implementation
- public boolean isCancelled() {
+ protected boolean isCancelled() {
return future.isCancelled();
}
@Implementation
- public boolean cancel(boolean mayInterruptIfRunning) {
+ protected boolean cancel(boolean mayInterruptIfRunning) {
return future.cancel(mayInterruptIfRunning);
}
@Implementation
- public Result get() throws InterruptedException, ExecutionException {
+ protected Result get() throws InterruptedException, ExecutionException {
return future.get();
}
@Implementation
- public Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+ protected Result get(long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
return future.get(timeout, unit);
}
@Implementation
- public AsyncTask<Params, Progress, Result> execute(final Params... params) {
+ protected AsyncTask<Params, Progress, Result> execute(final Params... params) {
status = AsyncTask.Status.RUNNING;
getBridge().onPreExecute();
@@ -97,7 +98,8 @@ public class ShadowAsyncTask<Params, Progress, Result> {
}
@Implementation
- public AsyncTask<Params, Progress, Result> executeOnExecutor(Executor executor, Params... params) {
+ protected AsyncTask<Params, Progress, Result> executeOnExecutor(
+ Executor executor, Params... params) {
status = AsyncTask.Status.RUNNING;
getBridge().onPreExecute();
@@ -113,19 +115,19 @@ public class ShadowAsyncTask<Params, Progress, Result> {
}
@Implementation
- public AsyncTask.Status getStatus() {
+ protected AsyncTask.Status getStatus() {
return status;
}
/**
- * Enqueue a call to {@link AsyncTask#onProgressUpdate(Object[])} on UI looper (or run it immediately
- * if the looper it is not paused).
+ * Enqueue a call to {@link AsyncTask#onProgressUpdate(Object[])} on UI looper (or run it
+ * immediately if the looper it is not paused).
*
* @param values The progress values to update the UI with.
* @see AsyncTask#publishProgress(Object[])
*/
@Implementation
- public void publishProgress(final Progress... values) {
+ protected void publishProgress(final Progress... values) {
ShadowApplication.getInstance().getForegroundThreadScheduler().post(new Runnable() {
@Override
public void run() {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAsyncTaskLoader.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAsyncTaskLoader.java
index 7cc673110..f96022642 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAsyncTaskLoader.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAsyncTaskLoader.java
@@ -15,12 +15,12 @@ public class ShadowAsyncTaskLoader<D> {
private BackgroundWorker worker;
@Implementation
- public void __constructor__(Context context) {
+ protected void __constructor__(Context context) {
worker = new BackgroundWorker();
}
@Implementation
- public void onForceLoad() {
+ protected void onForceLoad() {
FutureTask<D> future = new FutureTask<D>(worker) {
@Override
protected void done() {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioEffect.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioEffect.java
index c208e400b..a2348a65a 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioEffect.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioEffect.java
@@ -17,7 +17,7 @@ public class ShadowAudioEffect {
}
@Implementation
- public static AudioEffect.Descriptor[] queryEffects() {
+ protected static AudioEffect.Descriptor[] queryEffects() {
return DESCRIPTORS.toArray(new AudioEffect.Descriptor[DESCRIPTORS.size()]);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioManager.java
index b5930bb76..0486d8e1d 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioManager.java
@@ -58,19 +58,19 @@ public class ShadowAudioManager {
}
@Implementation
- public int getStreamMaxVolume(int streamType) {
+ protected int getStreamMaxVolume(int streamType) {
AudioStream stream = streamStatus.get(streamType);
return (stream != null) ? stream.getMaxVolume() : INVALID_VOLUME;
}
@Implementation
- public int getStreamVolume(int streamType) {
+ protected int getStreamVolume(int streamType) {
AudioStream stream = streamStatus.get(streamType);
return (stream != null) ? stream.getCurrentVolume() : INVALID_VOLUME;
}
@Implementation
- public void setStreamVolume(int streamType, int index, int flags) {
+ protected void setStreamVolume(int streamType, int index, int flags) {
AudioStream stream = streamStatus.get(streamType);
if (stream != null) {
stream.setCurrentVolume(index);
@@ -79,7 +79,8 @@ public class ShadowAudioManager {
}
@Implementation
- public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener l, int streamType, int durationHint) {
+ protected int requestAudioFocus(
+ android.media.AudioManager.OnAudioFocusChangeListener l, int streamType, int durationHint) {
lastAudioFocusRequest = new AudioFocusRequest(l, streamType, durationHint);
return nextResponseValue;
}
@@ -95,7 +96,7 @@ public class ShadowAudioManager {
}
@Implementation
- public int abandonAudioFocus(AudioManager.OnAudioFocusChangeListener l) {
+ protected int abandonAudioFocus(AudioManager.OnAudioFocusChangeListener l) {
lastAbandonedAudioFocusListener = l;
return nextResponseValue;
}
@@ -112,12 +113,12 @@ public class ShadowAudioManager {
}
@Implementation
- public int getRingerMode() {
+ protected int getRingerMode() {
return ringerMode;
}
@Implementation
- public void setRingerMode(int ringerMode) {
+ protected void setRingerMode(int ringerMode) {
if (!AudioManager.isValidRingerMode(ringerMode)) {
return;
}
@@ -132,12 +133,12 @@ public class ShadowAudioManager {
}
@Implementation
- public void setMode(int mode) {
+ protected void setMode(int mode) {
this.mode = mode;
}
@Implementation
- public int getMode() {
+ protected int getMode() {
return this.mode;
}
@@ -154,57 +155,57 @@ public class ShadowAudioManager {
}
@Implementation
- public void setWiredHeadsetOn(boolean on) {
+ protected void setWiredHeadsetOn(boolean on) {
wiredHeadsetOn = on;
}
@Implementation
- public boolean isWiredHeadsetOn() {
+ protected boolean isWiredHeadsetOn() {
return wiredHeadsetOn;
}
@Implementation
- public void setBluetoothA2dpOn(boolean on) {
+ protected void setBluetoothA2dpOn(boolean on) {
bluetoothA2dpOn = on;
}
@Implementation
- public boolean isBluetoothA2dpOn() {
+ protected boolean isBluetoothA2dpOn() {
return bluetoothA2dpOn;
}
@Implementation
- public void setSpeakerphoneOn(boolean on) {
+ protected void setSpeakerphoneOn(boolean on) {
isSpeakerphoneOn = on;
}
@Implementation
- public boolean isSpeakerphoneOn() {
+ protected boolean isSpeakerphoneOn() {
return isSpeakerphoneOn;
}
@Implementation
- public void setMicrophoneMute(boolean on) {
+ protected void setMicrophoneMute(boolean on) {
isMicrophoneMuted = on;
}
@Implementation
- public boolean isMicrophoneMute() {
+ protected boolean isMicrophoneMute() {
return isMicrophoneMuted;
}
@Implementation
- public boolean isBluetoothScoOn() {
+ protected boolean isBluetoothScoOn() {
return isBluetoothScoOn;
}
@Implementation
- public void setBluetoothScoOn(boolean isBluetoothScoOn) {
+ protected void setBluetoothScoOn(boolean isBluetoothScoOn) {
this.isBluetoothScoOn = isBluetoothScoOn;
}
@Implementation
- public boolean isMusicActive() {
+ protected boolean isMusicActive() {
return isMusicActive;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBaseAdapter.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBaseAdapter.java
index fa1c63daa..cab7e4027 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBaseAdapter.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBaseAdapter.java
@@ -14,7 +14,7 @@ public class ShadowBaseAdapter {
private boolean wasNotifyDataSetChangedCalled;
@Implementation
- public void notifyDataSetChanged() {
+ protected void notifyDataSetChanged() {
wasNotifyDataSetChangedCalled = true;
directlyOn(realBaseAdapter, BaseAdapter.class, "notifyDataSetChanged");
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBatteryManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBatteryManager.java
index 9404fdae4..6dad75085 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBatteryManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBatteryManager.java
@@ -16,7 +16,7 @@ public class ShadowBatteryManager {
private final Map<Integer, Integer> intProperties = new HashMap<>();
@Implementation(minSdk = M)
- public boolean isCharging() {
+ protected boolean isCharging() {
return isCharging;
}
@@ -25,7 +25,7 @@ public class ShadowBatteryManager {
}
@Implementation(minSdk = LOLLIPOP)
- public int getIntProperty(int id) {
+ protected int getIntProperty(int id) {
return intProperties.containsKey(id) ? intProperties.get(id) : Integer.MIN_VALUE;
}
@@ -34,7 +34,7 @@ public class ShadowBatteryManager {
}
@Implementation(minSdk = LOLLIPOP)
- public long getLongProperty(int id) {
+ protected long getLongProperty(int id) {
return longProperties.containsKey(id) ? longProperties.get(id) : Long.MIN_VALUE;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBinder.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBinder.java
index 32c0fa13f..46aed0230 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBinder.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBinder.java
@@ -17,7 +17,8 @@ public class ShadowBinder {
private static Integer callingPid;
@Implementation
- public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
+ protected boolean transact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
if (data != null) {
data.setDataPosition(0);
}
@@ -39,7 +40,7 @@ public class ShadowBinder {
}
@Implementation
- public static final int getCallingPid() {
+ protected static final int getCallingPid() {
if (callingPid != null) {
return callingPid;
}
@@ -47,7 +48,7 @@ public class ShadowBinder {
}
@Implementation
- public static final int getCallingUid() {
+ protected static final int getCallingUid() {
if (callingUid != null) {
return callingUid;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmap.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmap.java
index 44fc27454..98d40d783 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmap.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmap.java
@@ -17,6 +17,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
+import java.util.Arrays;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
@@ -56,6 +57,7 @@ public class ShadowBitmap {
private String description = "";
private boolean recycled = false;
private boolean hasMipMap;
+ private boolean isPremultiplied;
/**
* Returns a textual representation of the appearance of the object.
@@ -183,7 +185,7 @@ public class ShadowBitmap {
}
@Implementation
- public boolean compress(Bitmap.CompressFormat format, int quality, OutputStream stream) {
+ protected boolean compress(Bitmap.CompressFormat format, int quality, OutputStream stream) {
try {
stream.write((description + " compressed as " + format + " with quality " + quality).getBytes(UTF_8));
} catch (IOException e) {
@@ -194,17 +196,23 @@ public class ShadowBitmap {
}
@Implementation
- public static Bitmap createBitmap(int width, int height, Bitmap.Config config) {
+ protected static Bitmap createBitmap(int width, int height, Bitmap.Config config) {
return createBitmap((DisplayMetrics) null, width, height, config);
}
@Implementation(minSdk = JELLY_BEAN_MR1)
- public static Bitmap createBitmap(DisplayMetrics displayMetrics, int width, int height, Bitmap.Config config, boolean hasAlpha) {
+ protected static Bitmap createBitmap(
+ DisplayMetrics displayMetrics,
+ int width,
+ int height,
+ Bitmap.Config config,
+ boolean hasAlpha) {
return createBitmap((DisplayMetrics) null, width, height, config);
}
@Implementation(minSdk = JELLY_BEAN_MR1)
- public static Bitmap createBitmap(DisplayMetrics displayMetrics, int width, int height, Bitmap.Config config) {
+ protected static Bitmap createBitmap(
+ DisplayMetrics displayMetrics, int width, int height, Bitmap.Config config) {
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("width and height must be > 0");
}
@@ -224,14 +232,15 @@ public class ShadowBitmap {
}
@Implementation
- public static Bitmap createBitmap(Bitmap src) {
+ protected static Bitmap createBitmap(Bitmap src) {
ShadowBitmap shadowBitmap = Shadow.extract(src);
shadowBitmap.appendDescription(" created from Bitmap object");
return src;
}
@Implementation
- public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) {
+ protected static Bitmap createScaledBitmap(
+ Bitmap src, int dstWidth, int dstHeight, boolean filter) {
if (dstWidth == src.getWidth() && dstHeight == src.getHeight() && !filter) {
return src; // Return the original.
}
@@ -255,7 +264,7 @@ public class ShadowBitmap {
}
@Implementation
- public static Bitmap createBitmap(Bitmap src, int x, int y, int width, int height) {
+ protected static Bitmap createBitmap(Bitmap src, int x, int y, int width, int height) {
if (x == 0 && y == 0 && width == src.getWidth() && height == src.getHeight()) {
return src; // Return the original.
}
@@ -279,13 +288,14 @@ public class ShadowBitmap {
}
@Implementation
- public void setPixels(int[] pixels, int offset, int stride,
- int x, int y, int width, int height) {
+ protected void setPixels(
+ int[] pixels, int offset, int stride, int x, int y, int width, int height) {
this.colors = pixels;
}
@Implementation
- public static Bitmap createBitmap(Bitmap src, int x, int y, int width, int height, Matrix matrix, boolean filter) {
+ protected static Bitmap createBitmap(
+ Bitmap src, int x, int y, int width, int height, Matrix matrix, boolean filter) {
if (x == 0 && y == 0 && width == src.getWidth() && height == src.getHeight() && (matrix == null || matrix.isIdentity())) {
return src; // Return the original.
}
@@ -335,7 +345,7 @@ public class ShadowBitmap {
}
@Implementation
- public static Bitmap createBitmap(int[] colors, int width, int height, Bitmap.Config config) {
+ protected static Bitmap createBitmap(int[] colors, int width, int height, Bitmap.Config config) {
if (colors.length != width * height) {
throw new IllegalArgumentException("array length (" + colors.length + ") did not match width * height (" + (width * height) + ")");
}
@@ -351,7 +361,7 @@ public class ShadowBitmap {
}
@Implementation
- public int getPixel(int x, int y) {
+ protected int getPixel(int x, int y) {
internalCheckPixelAccess(x, y);
if (colors != null) {
// Note that getPixel() returns a non-premultiplied ARGB value; if
@@ -365,7 +375,7 @@ public class ShadowBitmap {
}
@Implementation
- public void setPixel(int x, int y, int color) {
+ protected void setPixel(int x, int y, int color) {
if (isRecycled()) {
throw new IllegalStateException("Can't call setPixel() on a recycled bitmap");
} else if (!isMutable()) {
@@ -379,14 +389,13 @@ public class ShadowBitmap {
}
/**
- * Note that this method will return a RuntimeException unless:
- * - {@code pixels} has the same length as the number of pixels of the bitmap.
- * - {@code x = 0}
- * - {@code y = 0}
- * - {@code width} and {@code height} height match the current bitmap's dimensions.
+ * Note that this method will return a RuntimeException unless: - {@code pixels} has the same
+ * length as the number of pixels of the bitmap. - {@code x = 0} - {@code y = 0} - {@code width}
+ * and {@code height} height match the current bitmap's dimensions.
*/
@Implementation
- public void getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height) {
+ protected void getPixels(
+ int[] pixels, int offset, int stride, int x, int y, int width, int height) {
if (x != 0 ||
y != 0 ||
width != getWidth() ||
@@ -403,27 +412,27 @@ public class ShadowBitmap {
}
@Implementation
- public int getRowBytes() {
+ protected int getRowBytes() {
return getBytesPerPixel(config) * getWidth();
}
@Implementation
- public int getByteCount() {
+ protected int getByteCount() {
return getRowBytes() * getHeight();
}
@Implementation
- public void recycle() {
+ protected void recycle() {
recycled = true;
}
@Implementation
- public final boolean isRecycled() {
+ protected final boolean isRecycled() {
return recycled;
}
@Implementation
- public Bitmap copy(Bitmap.Config config, boolean isMutable) {
+ protected Bitmap copy(Bitmap.Config config, boolean isMutable) {
Bitmap newBitmap = ReflectionHelpers.callConstructor(Bitmap.class);
ShadowBitmap shadowBitmap = Shadow.extract(newBitmap);
shadowBitmap.createdFromBitmap = realBitmap;
@@ -433,22 +442,22 @@ public class ShadowBitmap {
}
@Implementation(minSdk = KITKAT)
- public final int getAllocationByteCount() {
+ protected final int getAllocationByteCount() {
return getRowBytes() * getHeight();
}
@Implementation
- public final Bitmap.Config getConfig() {
+ protected final Bitmap.Config getConfig() {
return config;
}
@Implementation(minSdk = KITKAT)
- public void setConfig(Bitmap.Config config) {
+ protected void setConfig(Bitmap.Config config) {
this.config = config;
}
@Implementation
- public final boolean isMutable() {
+ protected final boolean isMutable() {
return mutable;
}
@@ -469,72 +478,72 @@ public class ShadowBitmap {
}
@Implementation
- public final boolean hasAlpha() {
+ protected final boolean hasAlpha() {
return hasAlpha;
}
@Implementation
- public void setHasAlpha(boolean hasAlpha) {
+ protected void setHasAlpha(boolean hasAlpha) {
this.hasAlpha = hasAlpha;
}
@Implementation(minSdk = JELLY_BEAN_MR1)
- public final boolean hasMipMap() {
+ protected final boolean hasMipMap() {
return hasMipMap;
}
@Implementation(minSdk = JELLY_BEAN_MR1)
- public final void setHasMipMap(boolean hasMipMap) {
+ protected final void setHasMipMap(boolean hasMipMap) {
this.hasMipMap = hasMipMap;
}
@Implementation(minSdk = KITKAT)
- public void setWidth(int width) {
+ protected void setWidth(int width) {
this.width = width;
}
@Implementation
- public int getWidth() {
+ protected int getWidth() {
return width;
}
@Implementation(minSdk = KITKAT)
- public void setHeight(int height) {
+ protected void setHeight(int height) {
this.height = height;
}
@Implementation
- public int getHeight() {
+ protected int getHeight() {
return height;
}
@Implementation
- public void setDensity(int density) {
+ protected void setDensity(int density) {
this.density = density;
}
@Implementation
- public int getDensity() {
+ protected int getDensity() {
return density;
}
@Implementation
- public int getGenerationId() {
+ protected int getGenerationId() {
return 0;
}
@Implementation(minSdk = M)
- public Bitmap createAshmemBitmap() {
+ protected Bitmap createAshmemBitmap() {
return realBitmap;
}
@Implementation
- public void eraseColor(int c) {
-
+ protected void eraseColor(int color) {
+ Arrays.fill(colors, color);
}
@Implementation
- public void writeToParcel(Parcel p, int flags) {
+ protected void writeToParcel(Parcel p, int flags) {
p.writeInt(width);
p.writeInt(height);
p.writeSerializable(config);
@@ -542,7 +551,7 @@ public class ShadowBitmap {
}
@Implementation
- public static Bitmap nativeCreateFromParcel(Parcel p) {
+ protected static Bitmap nativeCreateFromParcel(Parcel p) {
int parceledWidth = p.readInt();
int parceledHeight = p.readInt();
Bitmap.Config parceledConfig = (Bitmap.Config) p.readSerializable();
@@ -554,7 +563,7 @@ public class ShadowBitmap {
}
@Implementation
- public void copyPixelsFromBuffer(Buffer dst) {
+ protected void copyPixelsFromBuffer(Buffer dst) {
if (isRecycled()) {
throw new IllegalStateException("Can't call copyPixelsFromBuffer() on a recycled bitmap");
}
@@ -562,7 +571,7 @@ public class ShadowBitmap {
// See the related comment in #copyPixelsToBuffer(Buffer).
if (getBytesPerPixel(config) != INTERNAL_BYTES_PER_PIXEL) {
throw new RuntimeException("Not implemented: only Bitmaps with " + INTERNAL_BYTES_PER_PIXEL
- + " bytes per pixel are supported");
+ + " bytes per pixel are supported");
}
if (!(dst instanceof ByteBuffer)) {
throw new RuntimeException("Not implemented: unsupported Buffer subclass");
@@ -579,14 +588,14 @@ public class ShadowBitmap {
}
@Implementation
- public void copyPixelsToBuffer(Buffer dst) {
+ protected void copyPixelsToBuffer(Buffer dst) {
// Ensure that the Bitmap uses 4 bytes per pixel, since we always use 4 bytes per pixels
// internally. Clients of this API probably expect that the buffer size must be >=
// getByteCount(), but if we don't enforce this restriction then for RGB_4444 and other
// configs that value would be smaller then the buffer size we actually need.
if (getBytesPerPixel(config) != INTERNAL_BYTES_PER_PIXEL) {
throw new RuntimeException("Not implemented: only Bitmaps with " + INTERNAL_BYTES_PER_PIXEL
- + " bytes per pixel are supported");
+ + " bytes per pixel are supported");
}
if (!(dst instanceof ByteBuffer)) {
@@ -614,6 +623,36 @@ public class ShadowBitmap {
this.config = config;
}
+ @Implementation(minSdk = KITKAT)
+ protected void setPremultiplied(boolean isPremultiplied) {
+ this.isPremultiplied = isPremultiplied;
+ }
+
+ @Implementation(minSdk = KITKAT)
+ protected boolean isPremultiplied() {
+ return isPremultiplied;
+ }
+
+ @Implementation
+ protected boolean sameAs(Bitmap other) {
+ if (other == null) {
+ return false;
+ }
+ ShadowBitmap shadowOtherBitmap = Shadow.extract(other);
+ if (this.width != shadowOtherBitmap.width || this.height != shadowOtherBitmap.height) {
+ return false;
+ }
+ if (this.config != null
+ && shadowOtherBitmap.config != null
+ && this.config != shadowOtherBitmap.config) {
+ return false;
+ }
+ if (!Arrays.equals(colors, shadowOtherBitmap.colors)) {
+ return false;
+ }
+ return true;
+ }
+
public Bitmap getRealBitmap() {
return realBitmap;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapDrawable.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapDrawable.java
index 816c1f63e..14163d676 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapDrawable.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapDrawable.java
@@ -30,14 +30,14 @@ public class ShadowBitmapDrawable extends ShadowDrawable {
* @param canvas the canvas to draw on
*/
@Implementation
- public void draw(Canvas canvas) {
+ protected void draw(Canvas canvas) {
Paint paint = new Paint();
paint.setColorFilter(colorFilter);
canvas.drawBitmap(realBitmapDrawable.getBitmap(), 0, 0, paint);
}
@Implementation
- public Drawable mutate() {
+ protected Drawable mutate() {
Bitmap bitmap = realBitmapDrawable.getBitmap();
BitmapDrawable real = ReflectionHelpers.callConstructor(BitmapDrawable.class, ClassParameter.from(Bitmap.class, bitmap));
ShadowBitmapDrawable shadow = Shadow.extract(real);
@@ -47,7 +47,7 @@ public class ShadowBitmapDrawable extends ShadowDrawable {
}
@Implementation
- public void setColorFilter(ColorFilter colorFilter) {
+ protected void setColorFilter(ColorFilter colorFilter) {
this.colorFilter = colorFilter;
directlyOn(realBitmapDrawable, BitmapDrawable.class).setColorFilter(colorFilter);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapFactory.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapFactory.java
index 4f2346a5b..8a49e3c47 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapFactory.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapFactory.java
@@ -37,7 +37,8 @@ public class ShadowBitmapFactory {
private static Map<String, Point> widthAndHeightMap = new HashMap<>();
@Implementation
- public static Bitmap decodeResourceStream(Resources res, TypedValue value, InputStream is, Rect pad, BitmapFactory.Options opts) {
+ protected static Bitmap decodeResourceStream(
+ Resources res, TypedValue value, InputStream is, Rect pad, BitmapFactory.Options opts) {
Bitmap bitmap = directlyOn(BitmapFactory.class, "decodeResourceStream",
ClassParameter.from(Resources.class, res),
ClassParameter.from(TypedValue.class, value),
@@ -53,7 +54,7 @@ public class ShadowBitmapFactory {
}
@Implementation
- public static Bitmap decodeResource(Resources res, int id, BitmapFactory.Options options) {
+ protected static Bitmap decodeResource(Resources res, int id, BitmapFactory.Options options) {
if (id == 0) {
return null;
}
@@ -64,17 +65,17 @@ public class ShadowBitmapFactory {
}
@Implementation
- public static Bitmap decodeResource(Resources res, int id) {
+ protected static Bitmap decodeResource(Resources res, int id) {
return decodeResource(res, id, null);
}
@Implementation
- public static Bitmap decodeFile(String pathName) {
+ protected static Bitmap decodeFile(String pathName) {
return decodeFile(pathName, null);
}
@Implementation
- public static Bitmap decodeFile(String pathName, BitmapFactory.Options options) {
+ protected static Bitmap decodeFile(String pathName, BitmapFactory.Options options) {
Bitmap bitmap = create("file:" + pathName, options);
ShadowBitmap shadowBitmap = Shadow.extract(bitmap);
shadowBitmap.createdFromPath = pathName;
@@ -82,7 +83,8 @@ public class ShadowBitmapFactory {
}
@Implementation
- public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, BitmapFactory.Options opts) {
+ protected static Bitmap decodeFileDescriptor(
+ FileDescriptor fd, Rect outPadding, BitmapFactory.Options opts) {
Bitmap bitmap = create("fd:" + fd, opts);
ShadowBitmap shadowBitmap = Shadow.extract(bitmap);
shadowBitmap.createdFromFileDescriptor = fd;
@@ -90,12 +92,13 @@ public class ShadowBitmapFactory {
}
@Implementation
- public static Bitmap decodeStream(InputStream is) {
+ protected static Bitmap decodeStream(InputStream is) {
return decodeStream(is, null, null);
}
@Implementation
- public static Bitmap decodeStream(InputStream is, Rect outPadding, BitmapFactory.Options opts) {
+ protected static Bitmap decodeStream(
+ InputStream is, Rect outPadding, BitmapFactory.Options opts) {
byte[] ninePatchChunk = null;
if (is instanceof AssetInputStream) {
@@ -130,7 +133,7 @@ public class ShadowBitmapFactory {
}
@Implementation
- public static Bitmap decodeByteArray(byte[] data, int offset, int length) {
+ protected static Bitmap decodeByteArray(byte[] data, int offset, int length) {
Bitmap bitmap = decodeByteArray(data, offset, length, new BitmapFactory.Options());
ShadowBitmap shadowBitmap = Shadow.extract(bitmap);
shadowBitmap.createdFromBytes = data;
@@ -138,7 +141,8 @@ public class ShadowBitmapFactory {
}
@Implementation
- public static Bitmap decodeByteArray(byte[] data, int offset, int length, BitmapFactory.Options opts) {
+ protected static Bitmap decodeByteArray(
+ byte[] data, int offset, int length, BitmapFactory.Options opts) {
String desc = new String(data, UTF_8);
if (!Charset.forName("US-ASCII").newEncoder().canEncode(desc)) {
Checksum checksumEngine = new CRC32();
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapRegionDecoder.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapRegionDecoder.java
index 29ef61bb2..82f6c79b1 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapRegionDecoder.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBitmapRegionDecoder.java
@@ -24,22 +24,26 @@ public class ShadowBitmapRegionDecoder {
private int height;
@Implementation
- public static BitmapRegionDecoder newInstance(byte[] data, int offset, int length, boolean isShareable) throws IOException {
+ protected static BitmapRegionDecoder newInstance(
+ byte[] data, int offset, int length, boolean isShareable) throws IOException {
return fillWidthAndHeight(newInstance(), new ByteArrayInputStream(data));
}
@Implementation
- public static BitmapRegionDecoder newInstance(FileDescriptor fd, boolean isShareable) throws IOException {
+ protected static BitmapRegionDecoder newInstance(FileDescriptor fd, boolean isShareable)
+ throws IOException {
return fillWidthAndHeight(newInstance(), new FileInputStream(fd));
}
@Implementation
- public static BitmapRegionDecoder newInstance(InputStream is, boolean isShareable) throws IOException {
+ protected static BitmapRegionDecoder newInstance(InputStream is, boolean isShareable)
+ throws IOException {
return fillWidthAndHeight(newInstance(), is);
}
@Implementation
- public static BitmapRegionDecoder newInstance(String pathName, boolean isShareable) throws IOException {
+ protected static BitmapRegionDecoder newInstance(String pathName, boolean isShareable)
+ throws IOException {
return fillWidthAndHeight(newInstance(), new FileInputStream(pathName));
}
@@ -54,17 +58,17 @@ public class ShadowBitmapRegionDecoder {
}
@Implementation
- public int getWidth() {
+ protected int getWidth() {
return width;
}
@Implementation
- public int getHeight() {
+ protected int getHeight() {
return height;
}
@Implementation
- public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) {
+ protected Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) {
return Bitmap.createBitmap(rect.width(), rect.height(),
options.inPreferredConfig != null ? options.inPreferredConfig : Bitmap.Config.ARGB_8888);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java
index c2771ce81..e184e4dc9 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java
@@ -6,11 +6,14 @@ import static android.os.Build.VERSION_CODES.LOLLIPOP;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAdapter.LeScanCallback;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.os.ParcelUuid;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.robolectric.annotation.Implementation;
@@ -30,14 +33,15 @@ public class ShadowBluetoothAdapter {
private String name = "DefaultBluetoothDeviceName";
private int scanMode = BluetoothAdapter.SCAN_MODE_NONE;
private boolean isMultipleAdvertisementSupported = true;
+ private Map<Integer, Integer> profileConnectionStateData = new HashMap<>();
@Implementation
- public static BluetoothAdapter getDefaultAdapter() {
+ protected static BluetoothAdapter getDefaultAdapter() {
return (BluetoothAdapter) ShadowApplication.getInstance().getBluetoothAdapter();
}
@Implementation
- public Set<BluetoothDevice> getBondedDevices() {
+ protected Set<BluetoothDevice> getBondedDevices() {
return Collections.unmodifiableSet(bondedDevices);
}
@@ -53,31 +57,31 @@ public class ShadowBluetoothAdapter {
}
@Implementation
- public boolean startDiscovery() {
+ protected boolean startDiscovery() {
isDiscovering = true;
return true;
}
@Implementation
- public boolean cancelDiscovery() {
+ protected boolean cancelDiscovery() {
isDiscovering = false;
return true;
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public boolean startLeScan(LeScanCallback callback) {
+ protected boolean startLeScan(LeScanCallback callback) {
return startLeScan(null, callback);
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) {
+ protected boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) {
// Ignoring the serviceUuids param for now.
leScanCallbacks.add(callback);
return true;
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public void stopLeScan(LeScanCallback callback) {
+ protected void stopLeScan(LeScanCallback callback) {
leScanCallbacks.remove(callback);
}
@@ -93,34 +97,34 @@ public class ShadowBluetoothAdapter {
}
@Implementation
- public boolean isDiscovering() {
+ protected boolean isDiscovering() {
return isDiscovering;
}
@Implementation
- public boolean isEnabled() {
+ protected boolean isEnabled() {
return enabled;
}
@Implementation
- public boolean enable() {
+ protected boolean enable() {
enabled = true;
return true;
}
@Implementation
- public boolean disable() {
+ protected boolean disable() {
enabled = false;
return true;
}
@Implementation
- public String getAddress() {
+ protected String getAddress() {
return this.address;
}
@Implementation
- public int getState() {
+ protected int getState() {
return state;
}
@@ -158,38 +162,52 @@ public class ShadowBluetoothAdapter {
}
/**
- * Validate a Bluetooth address, such as "00:43:A8:23:10:F0"
- * Alphabetic characters must be uppercase to be valid.
+ * Validate a Bluetooth address, such as "00:43:A8:23:10:F0" Alphabetic characters must be
+ * uppercase to be valid.
*
- * @param address
- * Bluetooth address as string
+ * @param address Bluetooth address as string
* @return true if the address is valid, false otherwise
*/
@Implementation
- public static boolean checkBluetoothAddress(String address) {
+ protected static boolean checkBluetoothAddress(String address) {
if (address == null || address.length() != ADDRESS_LENGTH) {
return false;
}
for (int i = 0; i < ADDRESS_LENGTH; i++) {
char c = address.charAt(i);
switch (i % 3) {
- case 0:
- case 1:
- if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
- // hex character, OK
- break;
- }
- return false;
- case 2:
- if (c == ':') {
- break; // OK
- }
- return false;
+ case 0:
+ case 1:
+ if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
+ // hex character, OK
+ break;
+ }
+ return false;
+ case 2:
+ if (c == ':') {
+ break; // OK
+ }
+ return false;
}
}
return true;
}
+ /**
+ * Returns the connection state for the given Bluetooth {@code profile}, defaulting to {@link
+ * BluetoothProfile.STATE_DISCONNECTED} if the profile's connection state was never set.
+ *
+ * <p>Set a Bluetooth profile's connection state via {@link #setProfileConnectionState(int, int)}.
+ */
+ @Implementation
+ protected int getProfileConnectionState(int profile) {
+ Integer state = profileConnectionStateData.get(profile);
+ if (state == null) {
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
+ return state;
+ }
+
public void setAddress(String address) {
this.address = address;
}
@@ -205,4 +223,11 @@ public class ShadowBluetoothAdapter {
public void setIsMultipleAdvertisementSupported(boolean supported) {
isMultipleAdvertisementSupported = supported;
}
+
+ /**
+ *Sets the connection state {@code state} for the given BLuetoothProfile {@code profile}
+ */
+ public void setProfileConnectionState(int profile, int state) {
+ profileConnectionStateData.put(profile, state);
+ }
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothDevice.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothDevice.java
index 0ba4d95d9..d174681d3 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothDevice.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothDevice.java
@@ -36,7 +36,7 @@ public class ShadowBluetoothDevice {
* from invoking {@link android.bluetooth.BluetoothAdapter#getBluetoothService}.
*/
@Implementation
- public static IBluetooth getService() {
+ protected static IBluetooth getService() {
// Attempt to call the underlying getService method, but ignore any Exceptions. This allows us
// to easily create BluetoothDevices for testing purposes without having any actual Bluetooth
// capability.
@@ -53,7 +53,7 @@ public class ShadowBluetoothDevice {
}
@Implementation
- public String getName() {
+ protected String getName() {
return name;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothGatt.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothGatt.java
index 3ca92efda..034e97588 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothGatt.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothGatt.java
@@ -14,7 +14,6 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implements;
import org.robolectric.shadow.api.Shadow;
-/** Shadow for {@link BluetoothGatt}. */
@Implements(value = BluetoothGatt.class, minSdk = JELLY_BEAN_MR2)
public class ShadowBluetoothGatt {
@@ -31,11 +30,11 @@ public class ShadowBluetoothGatt {
Shadow.newInstance(
BluetoothGatt.class,
new Class<?>[] {
- iBluetoothGattClass,
- BluetoothDevice.class,
- Integer.TYPE,
- Boolean.TYPE,
- Integer.TYPE
+ iBluetoothGattClass,
+ BluetoothDevice.class,
+ Integer.TYPE,
+ Boolean.TYPE,
+ Integer.TYPE
},
new Object[] {null, device, 0, false, 0});
} else if (Build.VERSION.SDK_INT >= O) {
@@ -43,7 +42,7 @@ public class ShadowBluetoothGatt {
Shadow.newInstance(
BluetoothGatt.class,
new Class<?>[] {
- iBluetoothGattClass, BluetoothDevice.class, Integer.TYPE, Integer.TYPE
+ iBluetoothGattClass, BluetoothDevice.class, Integer.TYPE, Integer.TYPE
},
new Object[] {null, device, 0, 0});
} else if (Build.VERSION.SDK_INT >= LOLLIPOP) {
@@ -51,7 +50,7 @@ public class ShadowBluetoothGatt {
Shadow.newInstance(
BluetoothGatt.class,
new Class<?>[] {
- Context.class, iBluetoothGattClass, BluetoothDevice.class, Integer.TYPE
+ Context.class, iBluetoothGattClass, BluetoothDevice.class, Integer.TYPE
},
new Object[] {RuntimeEnvironment.application, null, device, 0});
} else {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothManager.java
index 5b80fae89..afd242f67 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothManager.java
@@ -10,8 +10,8 @@ import org.robolectric.annotation.Implements;
@Implements(value = BluetoothManager.class, minSdk = JELLY_BEAN_MR2)
public class ShadowBluetoothManager {
- @Implementation
- public BluetoothAdapter getAdapter() {
+ @Implementation
+ protected BluetoothAdapter getAdapter() {
return BluetoothAdapter.getDefaultAdapter();
}
} \ No newline at end of file
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothServerSocket.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothServerSocket.java
index c1b6dbc23..4d1c62e0d 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothServerSocket.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothServerSocket.java
@@ -10,7 +10,6 @@ import android.os.ParcelUuid;
import org.robolectric.annotation.Implements;
import org.robolectric.shadow.api.Shadow;
-/** Shadow for {@link BluetoothServerSocket}. */
@Implements(value = BluetoothServerSocket.class)
public class ShadowBluetoothServerSocket {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothSocket.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothSocket.java
new file mode 100644
index 000000000..2ec95a1c8
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothSocket.java
@@ -0,0 +1,54 @@
+package org.robolectric.shadows;
+
+import android.bluetooth.BluetoothSocket;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(BluetoothSocket.class)
+public class ShadowBluetoothSocket {
+ private final PipedOutputStream inputStreamFeeder = new PipedOutputStream();
+ private final PipedInputStream outputStreamSink = new PipedInputStream();
+ private final OutputStream outputStream;
+ private final InputStream inputStream;
+
+ public ShadowBluetoothSocket() {
+ try {
+ outputStream = new PipedOutputStream(outputStreamSink);
+ inputStream = new PipedInputStream(inputStreamFeeder);
+ } catch (IOException e) {
+ // Shouldn't happen. Rethrow as an unchecked exception.
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Returns {@link PipedOutputStream} that controls <b>input</b> stream of the {@link
+ * BluetoothSocket}.
+ */
+ public PipedOutputStream getInputStreamFeeder() {
+ return inputStreamFeeder;
+ }
+
+ /**
+ * Returns {@link PipedInputStream} that controls <b>output</b> stream of the {@link
+ * BluetoothSocket}.
+ */
+ public PipedInputStream getOutputStreamSink() {
+ return outputStreamSink;
+ }
+
+ @Implementation
+ protected InputStream getInputStream() {
+ return inputStream;
+ }
+
+ @Implementation
+ protected OutputStream getOutputStream() {
+ return outputStream;
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBroadcastPendingResult.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBroadcastPendingResult.java
index b4d44860f..2cd2058ee 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBroadcastPendingResult.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBroadcastPendingResult.java
@@ -123,7 +123,7 @@ public final class ShadowBroadcastPendingResult {
private final SettableFuture<BroadcastReceiver.PendingResult> finished = SettableFuture.create();
@Implementation
- public final void finish() {
+ protected final void finish() {
Preconditions.checkState(finished.set(pendingResult), "Broadcast already finished");
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBroadcastReceiver.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBroadcastReceiver.java
index 80396c1c2..b9659f14e 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBroadcastReceiver.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBroadcastReceiver.java
@@ -15,13 +15,13 @@ public class ShadowBroadcastReceiver {
private AtomicBoolean abort; // The abort state of the currently processed broadcast
@Implementation
- public void abortBroadcast() {
+ protected void abortBroadcast() {
// TODO probably needs a check to prevent calling this method from ordinary Broadcasts
abort.set(true);
}
@Implementation
- public void onReceive(Context context, Intent intent) {
+ protected void onReceive(Context context, Intent intent) {
if (abort == null || !abort.get()) {
receiver.onReceive(context, intent);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBuild.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBuild.java
index 2d440c608..c2d9786e9 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBuild.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBuild.java
@@ -1,8 +1,10 @@
package org.robolectric.shadows;
+import static android.os.Build.VERSION_CODES.L;
import static android.os.Build.VERSION_CODES.O;
import static org.robolectric.shadow.api.Shadow.directlyOn;
+import android.annotation.TargetApi;
import android.os.Build;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -105,6 +107,16 @@ public class ShadowBuild {
}
/**
+ * Sets the value of the {@link Build#SUPPORTED_64_BIT_ABIS} field. Available in Android L+.
+ *
+ * <p>It will be reset for the next test.
+ */
+ @TargetApi(L)
+ public static void setSupported64BitAbis(String[] supported64BitAbis) {
+ ReflectionHelpers.setStaticField(Build.class, "SUPPORTED_64_BIT_ABIS", supported64BitAbis);
+ }
+
+ /**
* Override return value from {@link Build#getRadioVersion()}
*
* @param radioVersion
@@ -114,7 +126,7 @@ public class ShadowBuild {
}
@Implementation
- public static String getRadioVersion() {
+ protected static String getRadioVersion() {
if (radioVersionOverride != null) {
return radioVersionOverride;
}
@@ -134,4 +146,11 @@ public class ShadowBuild {
// performStaticInitialization(Build.class);
}
+ // BEGIN-INTERNAL
+ /**
+ * Temporary constant that maps to Build.VERSION_CODES.Q.
+ * Useful for projects that still compile against P but want to explicitly run tests on Q.
+ */
+ public static final int Q = Build.VERSION_CODES.Q;
+ // END-INTERNAL
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCamera.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCamera.java
index d682b0f95..667d74fc3 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCamera.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCamera.java
@@ -15,6 +15,7 @@ import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.shadow.api.Shadow;
+import org.robolectric.util.ReflectionHelpers;
@Implements(Camera.class)
public class ShadowCamera {
@@ -35,18 +36,17 @@ public class ShadowCamera {
private static Map<Integer, Camera.CameraInfo> cameras = new HashMap<>();
- @RealObject
- private Camera realCamera;
+ @RealObject private Camera realCamera;
@Implementation
- public void __constructor__() {
+ protected void __constructor__() {
locked = true;
previewing = false;
released = false;
}
@Implementation
- public static Camera open() {
+ protected static Camera open() {
lastOpenedCameraId = 0;
Camera camera = newInstanceOf(Camera.class);
ShadowCamera shadowCamera = Shadow.extract(camera);
@@ -55,7 +55,7 @@ public class ShadowCamera {
}
@Implementation
- public static Camera open(int cameraId) {
+ protected static Camera open(int cameraId) {
lastOpenedCameraId = cameraId;
Camera camera = newInstanceOf(Camera.class);
ShadowCamera shadowCamera = Shadow.extract(camera);
@@ -68,17 +68,17 @@ public class ShadowCamera {
}
@Implementation
- public void unlock() {
+ protected void unlock() {
locked = false;
}
@Implementation
- public void reconnect() {
+ protected void reconnect() {
locked = true;
}
@Implementation
- public Camera.Parameters getParameters() {
+ protected Camera.Parameters getParameters() {
if (null == parameters) {
parameters = newInstanceOf(Camera.Parameters.class);
}
@@ -86,42 +86,42 @@ public class ShadowCamera {
}
@Implementation
- public void setParameters(Camera.Parameters params) {
+ protected void setParameters(Camera.Parameters params) {
parameters = params;
}
@Implementation
- public void setPreviewDisplay(SurfaceHolder holder) {
+ protected void setPreviewDisplay(SurfaceHolder holder) {
surfaceHolder = holder;
}
@Implementation
- public void startPreview() {
+ protected void startPreview() {
previewing = true;
}
@Implementation
- public void stopPreview() {
+ protected void stopPreview() {
previewing = false;
}
@Implementation
- public void release() {
+ protected void release() {
released = true;
}
@Implementation
- public void setPreviewCallback(Camera.PreviewCallback cb) {
+ protected void setPreviewCallback(Camera.PreviewCallback cb) {
previewCallback = cb;
}
@Implementation
- public void setOneShotPreviewCallback(Camera.PreviewCallback cb) {
+ protected void setOneShotPreviewCallback(Camera.PreviewCallback cb) {
previewCallback = cb;
}
@Implementation
- public void setPreviewCallbackWithBuffer(Camera.PreviewCallback cb) {
+ protected void setPreviewCallbackWithBuffer(Camera.PreviewCallback cb) {
previewCallback = cb;
}
@@ -137,7 +137,7 @@ public class ShadowCamera {
}
@Implementation
- public void addCallbackBuffer(byte[] callbackBuffer) {
+ protected void addCallbackBuffer(byte[] callbackBuffer) {
callbackBuffers.add(callbackBuffer);
}
@@ -146,7 +146,7 @@ public class ShadowCamera {
}
@Implementation
- public void setDisplayOrientation(int degrees) {
+ protected void setDisplayOrientation(int degrees) {
displayOrientation = degrees;
if (cameras.containsKey(id)) {
cameras.get(id).orientation = degrees;
@@ -158,13 +158,13 @@ public class ShadowCamera {
}
@Implementation
- public void autoFocus(Camera.AutoFocusCallback callback) {
+ protected void autoFocus(Camera.AutoFocusCallback callback) {
autoFocusCallback = callback;
autoFocusing = true;
}
@Implementation
- public void cancelAutoFocus() {
+ protected void cancelAutoFocus() {
autoFocusCallback = null;
autoFocusing = false;
}
@@ -186,14 +186,14 @@ public class ShadowCamera {
}
@Implementation
- public static void getCameraInfo(int cameraId, Camera.CameraInfo cameraInfo ) {
- Camera.CameraInfo foundCam = cameras.get( cameraId );
+ protected static void getCameraInfo(int cameraId, Camera.CameraInfo cameraInfo) {
+ Camera.CameraInfo foundCam = cameras.get(cameraId);
cameraInfo.facing = foundCam.facing;
cameraInfo.orientation = foundCam.orientation;
}
@Implementation
- public static int getNumberOfCameras() {
+ protected static int getNumberOfCameras() {
return cameras.size();
}
@@ -230,9 +230,8 @@ public class ShadowCamera {
}
/**
- * Add a mock {@code Camera.CameraInfo} object to simulate
- * the existence of one or more cameras. By default, no
- * cameras are defined.
+ * Add a mock {@code Camera.CameraInfo} object to simulate the existence of one or more cameras.
+ * By default, no cameras are defined.
*
* @param id The camera id
* @param camInfo The CameraInfo
@@ -245,9 +244,7 @@ public class ShadowCamera {
cameras.clear();
}
- /**
- * Shadows the Android {@code Camera.Parameters} class.
- */
+ /** Shadows the Android {@code Camera.Parameters} class. */
@Implements(Camera.Parameters.class)
public static class ShadowParameters {
@@ -260,11 +257,28 @@ public class ShadowCamera {
private int previewFpsMax = 30;
private int previewFps = 30;
private int exposureCompensation = 0;
+ private String flashMode;
private String focusMode;
+ private List<String> supportedFlashModes = new ArrayList<>();
private List<String> supportedFocusModes = new ArrayList<>();
+ private static List<Camera.Size> supportedPreviewSizes;
+
+ /**
+ * Explicitly initialize custom preview sizes array, to switch from default values to
+ * individually added.
+ */
+ public void initSupportedPreviewSizes() {
+ supportedPreviewSizes = new ArrayList<>();
+ }
+
+ /** Add custom preview sizes to supportedPreviewSizes. */
+ public void addSupportedPreviewSize(int width, int height) {
+ Camera.Size newSize = ReflectionHelpers.newInstance(Camera.class).new Size(width, height);
+ supportedPreviewSizes.add(newSize);
+ }
@Implementation
- public Camera.Size getPictureSize() {
+ protected Camera.Size getPictureSize() {
Camera.Size pictureSize = newInstanceOf(Camera.class).new Size(0, 0);
pictureSize.width = pictureWidth;
pictureSize.height = pictureHeight;
@@ -272,23 +286,23 @@ public class ShadowCamera {
}
@Implementation
- public int getPreviewFormat() {
+ protected int getPreviewFormat() {
return previewFormat;
}
@Implementation
- public void getPreviewFpsRange(int[] range) {
+ protected void getPreviewFpsRange(int[] range) {
range[0] = previewFpsMin;
range[1] = previewFpsMax;
}
@Implementation
- public int getPreviewFrameRate() {
+ protected int getPreviewFrameRate() {
return previewFps;
}
@Implementation
- public Camera.Size getPreviewSize() {
+ protected Camera.Size getPreviewSize() {
Camera.Size previewSize = newInstanceOf(Camera.class).new Size(0, 0);
previewSize.width = previewWidth;
previewSize.height = previewHeight;
@@ -296,7 +310,7 @@ public class ShadowCamera {
}
@Implementation
- public List<Camera.Size> getSupportedPictureSizes() {
+ protected List<Camera.Size> getSupportedPictureSizes() {
List<Camera.Size> supportedSizes = new ArrayList<>();
addSize(supportedSizes, 320, 240);
addSize(supportedSizes, 640, 480);
@@ -305,7 +319,7 @@ public class ShadowCamera {
}
@Implementation
- public List<Integer> getSupportedPictureFormats() {
+ protected List<Integer> getSupportedPictureFormats() {
List<Integer> formats = new ArrayList<>();
formats.add(ImageFormat.NV21);
formats.add(ImageFormat.JPEG);
@@ -313,7 +327,7 @@ public class ShadowCamera {
}
@Implementation
- public List<Integer> getSupportedPreviewFormats() {
+ protected List<Integer> getSupportedPreviewFormats() {
List<Integer> formats = new ArrayList<>();
formats.add(ImageFormat.NV21);
formats.add(ImageFormat.JPEG);
@@ -321,7 +335,7 @@ public class ShadowCamera {
}
@Implementation
- public List<int[]> getSupportedPreviewFpsRange() {
+ protected List<int[]> getSupportedPreviewFpsRange() {
List<int[]> supportedRanges = new ArrayList<>();
addRange(supportedRanges, 15000, 15000);
addRange(supportedRanges, 10000, 30000);
@@ -329,7 +343,7 @@ public class ShadowCamera {
}
@Implementation
- public List<Integer> getSupportedPreviewFrameRates() {
+ protected List<Integer> getSupportedPreviewFrameRates() {
List<Integer> supportedRates = new ArrayList<>();
supportedRates.add(10);
supportedRates.add(15);
@@ -338,11 +352,13 @@ public class ShadowCamera {
}
@Implementation
- public List<Camera.Size> getSupportedPreviewSizes() {
- List<Camera.Size> supportedSizes = new ArrayList<>();
- addSize(supportedSizes, 320, 240);
- addSize(supportedSizes, 640, 480);
- return supportedSizes;
+ protected List<Camera.Size> getSupportedPreviewSizes() {
+ if (supportedPreviewSizes == null) {
+ initSupportedPreviewSizes();
+ addSupportedPreviewSize(320, 240);
+ addSupportedPreviewSize(640, 480);
+ }
+ return supportedPreviewSizes;
}
public void setSupportedFocusModes(String... focusModes) {
@@ -350,83 +366,102 @@ public class ShadowCamera {
}
@Implementation
- public List<String> getSupportedFocusModes() {
+ protected List<String> getSupportedFocusModes() {
return supportedFocusModes;
}
@Implementation
- public String getFocusMode() {
+ protected String getFocusMode() {
return focusMode;
}
@Implementation
- public void setFocusMode(String focusMode) {
+ protected void setFocusMode(String focusMode) {
this.focusMode = focusMode;
}
@Implementation
- public void setPictureSize(int width, int height) {
+ protected void setPictureSize(int width, int height) {
pictureWidth = width;
pictureHeight = height;
}
@Implementation
- public void setPreviewFormat(int pixel_format) {
+ protected void setPreviewFormat(int pixel_format) {
previewFormat = pixel_format;
}
@Implementation
- public void setPreviewFpsRange(int min, int max) {
+ protected void setPreviewFpsRange(int min, int max) {
previewFpsMin = min;
previewFpsMax = max;
}
@Implementation
- public void setPreviewFrameRate(int fps) {
+ protected void setPreviewFrameRate(int fps) {
previewFps = fps;
}
@Implementation
- public void setPreviewSize(int width, int height) {
+ protected void setPreviewSize(int width, int height) {
previewWidth = width;
previewHeight = height;
}
@Implementation
- public void setRecordingHint(boolean recordingHint) {
+ protected void setRecordingHint(boolean recordingHint) {
// Do nothing - this prevents an NPE in the SDK code
}
@Implementation
- public void setRotation(int rotation) {
+ protected void setRotation(int rotation) {
// Do nothing - this prevents an NPE in the SDK code
}
@Implementation
- public int getMinExposureCompensation() {
+ protected int getMinExposureCompensation() {
return -6;
}
@Implementation
- public int getMaxExposureCompensation() {
+ protected int getMaxExposureCompensation() {
return 6;
}
@Implementation
- public float getExposureCompensationStep() {
+ protected float getExposureCompensationStep() {
return 0.5f;
}
@Implementation
- public int getExposureCompensation() {
+ protected int getExposureCompensation() {
return exposureCompensation;
}
@Implementation
- public void setExposureCompensation(int compensation) {
+ protected void setExposureCompensation(int compensation) {
exposureCompensation = compensation;
}
+ public void setSupportedFlashModes(String... flashModes) {
+ supportedFlashModes = Arrays.asList(flashModes);
+ }
+
+ @Implementation
+ protected List<String> getSupportedFlashModes() {
+ return supportedFlashModes;
+ }
+
+ @Implementation
+ protected String getFlashMode() {
+ return flashMode;
+ }
+
+ @Implementation
+ protected void setFlashMode(String flashMode) {
+ this.flashMode = flashMode;
+ }
+
public int getPreviewWidth() {
return previewWidth;
}
@@ -456,7 +491,6 @@ public class ShadowCamera {
range[1] = max;
ranges.add(range);
}
-
}
@Implements(Camera.Size.class)
@@ -464,7 +498,7 @@ public class ShadowCamera {
@RealObject private Camera.Size realCameraSize;
@Implementation
- public void __constructor__(Camera camera, int width, int height) {
+ protected void __constructor__(Camera camera, int width, int height) {
realCameraSize.width = width;
realCameraSize.height = height;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCameraCharacteristics.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCameraCharacteristics.java
new file mode 100644
index 000000000..e023a810f
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCameraCharacteristics.java
@@ -0,0 +1,39 @@
+package org.robolectric.shadows;
+
+import android.annotation.Nullable;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraCharacteristics.Key;
+import android.os.Build.VERSION_CODES;
+import com.google.common.base.Preconditions;
+import java.util.HashMap;
+import java.util.Map;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.util.ReflectionHelpers;
+
+@Implements(value = CameraCharacteristics.class, minSdk = VERSION_CODES.LOLLIPOP)
+public class ShadowCameraCharacteristics {
+
+ private final Map<Key<?>, Object> charactersKeyToValue = new HashMap<>();
+
+ /** Convenience method which returns a new instance of {@link CameraCharacteristics}. */
+ public static CameraCharacteristics newCameraCharacteristics() {
+ return ReflectionHelpers.callConstructor(CameraCharacteristics.class);
+ }
+
+ @Implementation
+ @Nullable
+ protected <T> T get(Key<T> key) {
+ return (T) charactersKeyToValue.get(key);
+ }
+
+ /**
+ * Sets the value for a given key.
+ *
+ * @throws IllegalArgumentException if there's an existing value for the key.
+ */
+ public <T> void set(Key<T> key, Object value) {
+ Preconditions.checkArgument(!charactersKeyToValue.containsKey(key));
+ charactersKeyToValue.put(key, value);
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCameraManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCameraManager.java
new file mode 100644
index 000000000..faecdfaa6
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCameraManager.java
@@ -0,0 +1,52 @@
+package org.robolectric.shadows;
+
+import android.annotation.NonNull;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.os.Build.VERSION_CODES;
+import com.google.common.base.Preconditions;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(value = CameraManager.class, minSdk = VERSION_CODES.LOLLIPOP)
+public class ShadowCameraManager {
+
+ // LinkedHashMap used to ensure getCameraIdList returns ids in the order in which they were added
+ private final Map<String, CameraCharacteristics> cameraIdToCharacteristics =
+ new LinkedHashMap<>();
+
+ @Implementation
+ @NonNull
+ protected String[] getCameraIdList() throws CameraAccessException {
+ Set<String> cameraIds = cameraIdToCharacteristics.keySet();
+ return cameraIds.toArray(new String[0]);
+ }
+
+ @Implementation
+ @NonNull
+ protected CameraCharacteristics getCameraCharacteristics(@NonNull String cameraId) {
+ Preconditions.checkNotNull(cameraId);
+ CameraCharacteristics characteristics = cameraIdToCharacteristics.get(cameraId);
+ Preconditions.checkArgument(characteristics != null);
+ return characteristics;
+ }
+
+ /**
+ * Adds the given cameraId and characteristics to this shadow.
+ *
+ * <p>The result from {@link #getCameraIdList()} will be in the order in which cameras were added.
+ *
+ * @throws IllegalArgumentException if there's already an existing camera with the given id.
+ */
+ public void addCamera(@NonNull String cameraId, @NonNull CameraCharacteristics characteristics) {
+ Preconditions.checkNotNull(cameraId);
+ Preconditions.checkNotNull(characteristics);
+ Preconditions.checkArgument(!cameraIdToCharacteristics.containsKey(cameraId));
+
+ cameraIdToCharacteristics.put(cameraId, characteristics);
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCanvas.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCanvas.java
index 497bf610e..d308315c7 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCanvas.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCanvas.java
@@ -54,7 +54,7 @@ public class ShadowCanvas {
}
@Implementation
- public void __constructor__(Bitmap bitmap) {
+ protected void __constructor__(Bitmap bitmap) {
this.targetBitmap = bitmap;
}
@@ -69,12 +69,12 @@ public class ShadowCanvas {
}
@Implementation
- public void setBitmap(Bitmap bitmap) {
+ protected void setBitmap(Bitmap bitmap) {
targetBitmap = bitmap;
}
@Implementation
- public void drawText(String text, float x, float y, Paint paint) {
+ protected void drawText(String text, float x, float y, Paint paint) {
drawnTextEventHistory.add(new TextHistoryEvent(x, y, paint, text));
}
@@ -95,42 +95,42 @@ public class ShadowCanvas {
}
@Implementation
- public void translate(float x, float y) {
+ protected void translate(float x, float y) {
this.translateX = x;
this.translateY = y;
}
@Implementation
- public void scale(float sx, float sy) {
+ protected void scale(float sx, float sy) {
this.scaleX = sx;
this.scaleY = sy;
}
@Implementation
- public void scale(float sx, float sy, float px, float py) {
+ protected void scale(float sx, float sy, float px, float py) {
this.scaleX = sx;
this.scaleY = sy;
}
@Implementation
- public void drawPaint(Paint paint) {
+ protected void drawPaint(Paint paint) {
drawnPaint = paint;
}
@Implementation
- public void drawColor(int color) {
+ protected void drawColor(int color) {
appendDescription("draw color " + color);
}
@Implementation
- public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
+ protected void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
describeBitmap(bitmap, paint);
int x = (int) (left + translateX);
int y = (int) (top + translateY);
if (x != 0 || y != 0) {
appendDescription(" at (" + x + "," + y + ")");
- }
+ }
if (scaleX != 1 && scaleY != 1) {
appendDescription(" scaled by (" + scaleX + "," + scaleY + ")");
@@ -138,7 +138,7 @@ public class ShadowCanvas {
}
@Implementation
- public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
+ protected void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
describeBitmap(bitmap, paint);
StringBuilder descriptionBuilder = new StringBuilder();
@@ -154,7 +154,7 @@ public class ShadowCanvas {
}
@Implementation
- public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
+ protected void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
describeBitmap(bitmap, paint);
StringBuilder descriptionBuilder = new StringBuilder();
@@ -170,7 +170,7 @@ public class ShadowCanvas {
}
@Implementation
- public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
+ protected void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
describeBitmap(bitmap, paint);
ShadowMatrix shadowMatrix = Shadow.extract(matrix);
@@ -178,7 +178,7 @@ public class ShadowCanvas {
}
@Implementation
- public void drawPath(Path path, Paint paint) {
+ protected void drawPath(Path path, Paint paint) {
pathPaintEvents.add(new PathPaintHistoryEvent(new Path(path), new Paint(paint)));
separateLines();
@@ -187,34 +187,39 @@ public class ShadowCanvas {
}
@Implementation
- public void drawCircle(float cx, float cy, float radius, Paint paint) {
+ protected void drawCircle(float cx, float cy, float radius, Paint paint) {
circlePaintEvents.add(new CirclePaintHistoryEvent(cx, cy, radius, paint));
}
@Implementation
- public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) {
+ protected void drawArc(
+ RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) {
arcPaintEvents.add(new ArcPaintHistoryEvent(oval, startAngle, sweepAngle, useCenter, paint));
}
@Implementation
- public void drawRect(float left, float top, float right, float bottom, Paint paint) {
+ protected void drawRect(float left, float top, float right, float bottom, Paint paint) {
rectPaintEvents.add(new RectPaintHistoryEvent(left, top, right, bottom, paint));
}
@Implementation
- public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
+ protected void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
linePaintEvents.add(new LinePaintHistoryEvent(startX, startY, stopX, stopY, paint));
}
@Implementation
- public void drawOval(RectF oval, Paint paint) {
+ protected void drawOval(RectF oval, Paint paint) {
ovalPaintEvents.add(new OvalPaintHistoryEvent(oval, paint));
}
@Implementation
- public void restore() {
+ protected int save() {
+ return 1;
}
+ @Implementation
+ protected void restore() {}
+
private void describeBitmap(Bitmap bitmap, Paint paint) {
separateLines();
@@ -313,12 +318,12 @@ public class ShadowCanvas {
}
@Implementation
- public int getWidth() {
+ protected int getWidth() {
return width;
}
@Implementation
- public int getHeight() {
+ protected int getHeight() {
return height;
}
@@ -444,7 +449,7 @@ public class ShadowCanvas {
public final Paint paint;
public ArcPaintHistoryEvent(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
- Paint paint) {
+ Paint paint) {
this.oval = oval;
this.startAngle = startAngle;
this.sweepAngle = sweepAngle;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCaptioningManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCaptioningManager.java
index c41a73c34..04977beb5 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCaptioningManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCaptioningManager.java
@@ -1,6 +1,9 @@
package org.robolectric.shadows;
+import android.annotation.NonNull;
+import android.util.ArraySet;
import android.view.accessibility.CaptioningManager;
+import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -10,6 +13,8 @@ public class ShadowCaptioningManager {
private float fontScale = 1;
private boolean isEnabled = false;
+ private final ArraySet<CaptioningChangeListener> listeners = new ArraySet<>();
+
/** Returns 1.0 as default or the most recent value passed to {@link #setFontScale()} */
@Implementation(minSdk = 19)
protected float getFontScale() {
@@ -19,6 +24,10 @@ public class ShadowCaptioningManager {
/** Sets the value to be returned by {@link CaptioningManager#getFontScale()} */
public void setFontScale(float fontScale) {
this.fontScale = fontScale;
+
+ for (CaptioningChangeListener captioningChangeListener : listeners) {
+ captioningChangeListener.onFontScaleChanged(fontScale);
+ }
}
/** Returns false or the most recent value passed to {@link #setEnabled(boolean)} */
@@ -31,4 +40,14 @@ public class ShadowCaptioningManager {
public void setEnabled(boolean isEnabled) {
this.isEnabled = isEnabled;
}
+
+ @Implementation(minSdk = 19)
+ protected void addCaptioningChangeListener(@NonNull CaptioningChangeListener listener) {
+ listeners.add(listener);
+ }
+
+ @Implementation(minSdk = 19)
+ protected void removeCaptioningChangeListener(@NonNull CaptioningChangeListener listener) {
+ listeners.remove(listener);
+ }
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCarrierConfigManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCarrierConfigManager.java
new file mode 100644
index 000000000..62f748544
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCarrierConfigManager.java
@@ -0,0 +1,36 @@
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.M;
+
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.util.SparseArray;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(value = CarrierConfigManager.class, minSdk = M)
+public class ShadowCarrierConfigManager {
+
+ private SparseArray<PersistableBundle> bundles = new SparseArray<>();
+
+ /**
+ * Returns {@link android.os.PersistableBundle} previously set by {@link #setConfigForSubId(int)},
+ * or default values for an invalid {@code subId}.
+ */
+ @Implementation
+ protected PersistableBundle getConfigForSubId(int subId) {
+ PersistableBundle persistableBundle = bundles.get(subId);
+ if (persistableBundle == null) {
+ return new PersistableBundle();
+ }
+ return persistableBundle;
+ }
+
+ /**
+ * Sets that the {@code config} PersistableBundle for a particular {@code subId}; controls the
+ * return value of {@link CarrierConfigManager#getConfigForSubId()}.
+ */
+ public void setConfigForSubId(int subId, PersistableBundle config) {
+ bundles.put(subId, config);
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowChoreographer.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowChoreographer.java
index 93f01bc1f..4dde1fd46 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowChoreographer.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowChoreographer.java
@@ -70,7 +70,7 @@ public class ShadowChoreographer {
}
@Implementation
- public static Choreographer getInstance() {
+ protected static Choreographer getInstance() {
return instance.get();
}
@@ -82,23 +82,24 @@ public class ShadowChoreographer {
* AnimationHandler would result in endless looping (the execution of the task results in a new
* animation task created and scheduled to the front of the event loop queue).
*
- * To prevent endless looping, a test may call {@link #setPostCallbackDelay(int)} to specify a
+ * <p>To prevent endless looping, a test may call {@link #setPostCallbackDelay(int)} to specify a
* small delay when animation is scheduled.
*
* @see #setPostCallbackDelay(int)
*/
@Implementation
- public void postCallback(int callbackType, Runnable action, Object token) {
+ protected void postCallback(int callbackType, Runnable action, Object token) {
postCallbackDelayed(callbackType, action, token, postCallbackDelayMillis);
}
@Implementation
- public void postCallbackDelayed(int callbackType, Runnable action, Object token, long delayMillis) {
+ protected void postCallbackDelayed(
+ int callbackType, Runnable action, Object token, long delayMillis) {
handler.postDelayed(action, delayMillis);
}
@Implementation
- public void removeCallbacks(int callbackType, Runnable action, Object token) {
+ protected void removeCallbacks(int callbackType, Runnable action, Object token) {
handler.removeCallbacks(action, token);
}
@@ -110,18 +111,18 @@ public class ShadowChoreographer {
* AnimationHandler would result in endless looping (the execution of the task results in a new
* animation task created and scheduled to the front of the event loop queue).
*
- * To prevent endless looping, a test may call {@link #setPostFrameCallbackDelay(int)} to
+ * <p>To prevent endless looping, a test may call {@link #setPostFrameCallbackDelay(int)} to
* specify a small delay when animation is scheduled.
*
* @see #setPostCallbackDelay(int)
*/
@Implementation
- public void postFrameCallback(final FrameCallback callback) {
+ protected void postFrameCallback(final FrameCallback callback) {
postFrameCallbackDelayed(callback, postFrameCallbackDelayMillis);
}
@Implementation
- public void postFrameCallbackDelayed(final FrameCallback callback, long delayMillis) {
+ protected void postFrameCallbackDelayed(final FrameCallback callback, long delayMillis) {
handler.postAtTime(new Runnable() {
@Override public void run() {
callback.doFrame(getFrameTimeNanos());
@@ -130,12 +131,12 @@ public class ShadowChoreographer {
}
@Implementation
- public void removeFrameCallback(FrameCallback callback) {
+ protected void removeFrameCallback(FrameCallback callback) {
handler.removeCallbacksAndMessages(callback);
}
@Implementation
- public long getFrameTimeNanos() {
+ protected long getFrameTimeNanos() {
final long now = nanoTime;
nanoTime += ShadowChoreographer.FRAME_INTERVAL;
return now;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowClipboardManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowClipboardManager.java
index 33f75397e..748d9439c 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowClipboardManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowClipboardManager.java
@@ -24,7 +24,7 @@ public class ShadowClipboardManager {
private ClipData clip;
@Implementation
- public void setPrimaryClip(ClipData clip) {
+ protected void setPrimaryClip(ClipData clip) {
if (getApiLevel() >= N) {
if (clip != null) {
clip.prepareToLeaveProcess(true);
@@ -43,37 +43,37 @@ public class ShadowClipboardManager {
}
@Implementation
- public ClipData getPrimaryClip() {
+ protected ClipData getPrimaryClip() {
return clip;
}
@Implementation
- public ClipDescription getPrimaryClipDescription() {
+ protected ClipDescription getPrimaryClipDescription() {
return clip == null ? null : clip.getDescription();
}
@Implementation
- public boolean hasPrimaryClip() {
+ protected boolean hasPrimaryClip() {
return clip != null;
}
@Implementation
- public void addPrimaryClipChangedListener(OnPrimaryClipChangedListener listener) {
+ protected void addPrimaryClipChangedListener(OnPrimaryClipChangedListener listener) {
listeners.add(listener);
}
@Implementation
- public void removePrimaryClipChangedListener(OnPrimaryClipChangedListener listener) {
+ protected void removePrimaryClipChangedListener(OnPrimaryClipChangedListener listener) {
listeners.remove(listener);
}
@Implementation
- public void setText(CharSequence text) {
+ protected void setText(CharSequence text) {
setPrimaryClip(ClipData.newPlainText(null, text));
}
@Implementation
- public boolean hasText() {
+ protected boolean hasText() {
CharSequence text = directlyOn(realClipboardManager, ClipboardManager.class).getText();
return text != null && text.length() > 0;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowColor.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowColor.java
index eb7d32183..89609cc52 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowColor.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowColor.java
@@ -9,12 +9,12 @@ public class ShadowColor {
/**
* This is implemented in native code in the Android SDK.
*
- * Since HSV == HSB then the implementation from {@link java.awt.Color} can be used,
- * with a small adjustment to the representation of the hue.
+ * <p>Since HSV == HSB then the implementation from {@link java.awt.Color} can be used, with a
+ * small adjustment to the representation of the hue.
*
- * {@link java.awt.Color} represents hue as 0..1 (where 1 == 100% == 360 degrees),
- * while {@link android.graphics.Color} represents hue as 0..360 degrees. The correct hue
- * can be calculated by multiplying with 360.
+ * <p>{@link java.awt.Color} represents hue as 0..1 (where 1 == 100% == 360 degrees), while {@link
+ * android.graphics.Color} represents hue as 0..360 degrees. The correct hue can be calculated by
+ * multiplying with 360.
*
* @param red Red component
* @param green Green component
@@ -22,13 +22,13 @@ public class ShadowColor {
* @param hsv Array to store HSV components
*/
@Implementation
- public static void RGBToHSV(int red, int green, int blue, float hsv[]) {
+ protected static void RGBToHSV(int red, int green, int blue, float hsv[]) {
java.awt.Color.RGBtoHSB(red, green, blue, hsv);
hsv[0] = hsv[0] * 360;
}
@Implementation
- public static int HSVToColor(int alpha, float hsv[]) {
+ protected static int HSVToColor(int alpha, float hsv[]) {
int rgb = java.awt.Color.HSBtoRGB(hsv[0] / 360, hsv[1], hsv[2]);
return Color.argb(alpha, Color.red(rgb), Color.green(rgb), Color.blue(rgb));
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowColorMatrixColorFilter.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowColorMatrixColorFilter.java
index 147fdc4fa..2016601f3 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowColorMatrixColorFilter.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowColorMatrixColorFilter.java
@@ -11,12 +11,12 @@ public class ShadowColorMatrixColorFilter {
private ColorMatrix matrix;
@Implementation
- public void __constructor__(ColorMatrix matrix) {
+ protected void __constructor__(ColorMatrix matrix) {
this.matrix = matrix;
}
@Implementation
- public void __constructor__(float[] array) {
+ protected void __constructor__(float[] array) {
this.matrix = new ColorMatrix(array);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCompoundButton.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCompoundButton.java
index bc1e58c6a..a8357d8cc 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCompoundButton.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCompoundButton.java
@@ -17,13 +17,13 @@ public class ShadowCompoundButton extends ShadowTextView {
private Drawable buttonDrawable;
@Implementation
- public void setButtonDrawable(int buttonDrawableId) {
+ protected void setButtonDrawable(int buttonDrawableId) {
this.buttonDrawableId = buttonDrawableId;
directlyOn(realObject, CompoundButton.class, "setButtonDrawable", from(int.class, buttonDrawableId));
}
@Implementation
- public void setButtonDrawable(Drawable buttonDrawable) {
+ protected void setButtonDrawable(Drawable buttonDrawable) {
this.buttonDrawable = buttonDrawable;
directlyOn(realObject, CompoundButton.class, "setButtonDrawable", from(Drawable.class, buttonDrawable));
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowConnectivityManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowConnectivityManager.java
index aaed90052..79140ba27 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowConnectivityManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowConnectivityManager.java
@@ -1,14 +1,19 @@
package org.robolectric.shadows;
+import static android.os.Build.VERSION_CODES.KITKAT;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static android.os.Build.VERSION_CODES.M;
+import static android.os.Build.VERSION_CODES.N;
+import static android.os.Build.VERSION_CODES.O;
import static org.robolectric.RuntimeEnvironment.getApiLevel;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.OnNetworkActiveListener;
import android.net.Network;
+import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
+import android.os.Handler;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -38,6 +43,8 @@ public class ShadowConnectivityManager {
private HashSet<ConnectivityManager.OnNetworkActiveListener> onNetworkActiveListeners =
new HashSet<>();
private Map<Network, Boolean> reportedNetworkConnectivity = new HashMap<>();
+ private Map<Network, NetworkCapabilities> networkCapabilitiesMap = new HashMap<>();
+ private String captivePortalServerUrl = "http://10.0.0.2";
public ShadowConnectivityManager() {
NetworkInfo wifi = ShadowNetworkInfo.newInstance(NetworkInfo.DetailedState.DISCONNECTED,
@@ -72,7 +79,16 @@ public class ShadowConnectivityManager {
}
@Implementation(minSdk = LOLLIPOP)
- public void registerNetworkCallback(NetworkRequest request, ConnectivityManager.NetworkCallback networkCallback) {
+ protected void registerNetworkCallback(
+ NetworkRequest request, ConnectivityManager.NetworkCallback networkCallback) {
+ registerNetworkCallback(request, networkCallback, null);
+ }
+
+ @Implementation(minSdk = O)
+ protected void registerNetworkCallback(
+ NetworkRequest request,
+ ConnectivityManager.NetworkCallback networkCallback,
+ Handler handler) {
networkCallbacks.add(networkCallback);
}
@@ -83,7 +99,7 @@ public class ShadowConnectivityManager {
}
@Implementation(minSdk = LOLLIPOP)
- public void unregisterNetworkCallback (ConnectivityManager.NetworkCallback networkCallback) {
+ protected void unregisterNetworkCallback(ConnectivityManager.NetworkCallback networkCallback) {
if (networkCallback == null) {
throw new IllegalArgumentException("Invalid NetworkCallback");
}
@@ -93,7 +109,7 @@ public class ShadowConnectivityManager {
}
@Implementation
- public NetworkInfo getActiveNetworkInfo() {
+ protected NetworkInfo getActiveNetworkInfo() {
return activeNetworkInfo;
}
@@ -102,7 +118,7 @@ public class ShadowConnectivityManager {
* @see #setNetworkInfo(int, NetworkInfo)
*/
@Implementation(minSdk = M)
- public Network getActiveNetwork() {
+ protected Network getActiveNetwork() {
if (defaultNetworkActive) {
return netIdToNetwork.get(getActiveNetworkInfo().getType());
}
@@ -114,7 +130,7 @@ public class ShadowConnectivityManager {
* @see #setNetworkInfo(int, NetworkInfo)
*/
@Implementation
- public NetworkInfo[] getAllNetworkInfo() {
+ protected NetworkInfo[] getAllNetworkInfo() {
// todo(xian): is `defaultNetworkActive` really relevant here?
if (defaultNetworkActive) {
return networkTypeToNetworkInfo
@@ -125,46 +141,49 @@ public class ShadowConnectivityManager {
}
@Implementation
- public NetworkInfo getNetworkInfo(int networkType) {
+ protected NetworkInfo getNetworkInfo(int networkType) {
return networkTypeToNetworkInfo.get(networkType);
}
@Implementation(minSdk = LOLLIPOP)
- public NetworkInfo getNetworkInfo(Network network) {
+ protected NetworkInfo getNetworkInfo(Network network) {
+ if (network == null) {
+ return null;
+ }
ShadowNetwork shadowNetwork = Shadow.extract(network);
return netIdToNetworkInfo.get(shadowNetwork.getNetId());
}
@Implementation(minSdk = LOLLIPOP)
- public Network[] getAllNetworks() {
+ protected Network[] getAllNetworks() {
return netIdToNetwork.values().toArray(new Network[netIdToNetwork.size()]);
}
@Implementation
- public boolean getBackgroundDataSetting() {
+ protected boolean getBackgroundDataSetting() {
return backgroundDataSetting;
}
@Implementation
- public void setNetworkPreference(int preference) {
+ protected void setNetworkPreference(int preference) {
networkPreference = preference;
}
@Implementation
- public int getNetworkPreference() {
+ protected int getNetworkPreference() {
return networkPreference;
}
/**
- * Counts {@link ConnectivityManager#TYPE_MOBILE} networks as metered.
- * Other types will be considered unmetered.
+ * Counts {@link ConnectivityManager#TYPE_MOBILE} networks as metered. Other types will be
+ * considered unmetered.
*
* @return `true` if the active network is metered, otherwise `false`.
* @see #setActiveNetworkInfo(NetworkInfo)
* @see #setDefaultNetworkActive(boolean)
*/
@Implementation
- public boolean isActiveNetworkMetered() {
+ protected boolean isActiveNetworkMetered() {
if (defaultNetworkActive && activeNetworkInfo != null) {
return activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE;
} else {
@@ -173,13 +192,13 @@ public class ShadowConnectivityManager {
}
@Implementation(minSdk = M)
- public boolean bindProcessToNetwork(Network network) {
+ protected boolean bindProcessToNetwork(Network network) {
processBoundNetwork = network;
return true;
}
@Implementation(minSdk = M)
- public Network getBoundNetworkForProcess() {
+ protected Network getBoundNetworkForProcess() {
return processBoundNetwork;
}
@@ -187,6 +206,23 @@ public class ShadowConnectivityManager {
networkTypeToNetworkInfo.put(networkType, networkInfo);
}
+ /**
+ * Returns the captive portal URL previously set with {@link #setCaptivePortalServerUrl}.
+ */
+ @Implementation(minSdk = N)
+ protected String getCaptivePortalServerUrl() {
+ return captivePortalServerUrl;
+ }
+
+ /**
+ * Sets the captive portal URL, which will be returned in {@link #getCaptivePortalServerUrl}.
+ *
+ * @param captivePortalServerUrl the url of captive portal.
+ */
+ public void setCaptivePortalServerUrl(String captivePortalServerUrl) {
+ this.captivePortalServerUrl = captivePortalServerUrl;
+ }
+
@HiddenApi @Implementation
public void setBackgroundDataSetting(boolean b) {
backgroundDataSetting = b;
@@ -298,4 +334,37 @@ public class ShadowConnectivityManager {
protected void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
reportedNetworkConnectivity.put(network, new Boolean(hasConnectivity));
}
+
+ /**
+ * Gets the network capabilities of a given {@link Network}.
+ *
+ * @param network The {@link Network} object identifying the network in question.
+ * @return The {@link android.net.NetworkCapabilities} for the network.
+ * @see #setNetworkCapabilities(Network, NetworkCapabilities)
+ */
+ @Implementation(minSdk = LOLLIPOP)
+ protected NetworkCapabilities getNetworkCapabilities(Network network) {
+ return networkCapabilitiesMap.get(network);
+ }
+
+ /**
+ * Sets network capability and affects the result of {@link
+ * ConnectivityManager#getNetworkCapabilities(Network)}
+ *
+ * @param network The {@link Network} object identifying the network in question.
+ * @param networkCapabilities The {@link android.net.NetworkCapabilities} for the network.
+ */
+ public void setNetworkCapabilities(Network network, NetworkCapabilities networkCapabilities) {
+ networkCapabilitiesMap.put(network, networkCapabilities);
+ }
+
+ /**
+ * Sets the value for enabling/disabling airplane mode
+ *
+ * @param enable new status for airplane mode
+ */
+ @Implementation(minSdk = KITKAT)
+ protected void setAirplaneMode(boolean enable) {
+ ShadowSettings.setAirplaneMode(enable);
+ }
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentObserver.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentObserver.java
index 247a74978..c0b989c77 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentObserver.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentObserver.java
@@ -13,12 +13,12 @@ public class ShadowContentObserver {
private ContentObserver realObserver;
@Implementation
- public void dispatchChange(boolean selfChange, Uri uri) {
+ protected void dispatchChange(boolean selfChange, Uri uri) {
realObserver.onChange(selfChange, uri);
}
@Implementation
- public void dispatchChange(boolean selfChange) {
+ protected void dispatchChange(boolean selfChange) {
realObserver.onChange(selfChange);
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProvider.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProvider.java
index 33d8dbb97..fa713eb3f 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProvider.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProvider.java
@@ -19,7 +19,7 @@ public class ShadowContentProvider {
}
@Implementation(minSdk = KITKAT)
- public String getCallingPackage() {
+ protected String getCallingPackage() {
if (callingPackage != null) {
return callingPackage;
} else {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProviderClient.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProviderClient.java
index 2b7ee24f1..ce4ec846d 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProviderClient.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProviderClient.java
@@ -6,9 +6,7 @@ import android.content.ContentProvider;
import android.content.ContentProviderClient;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
-import android.content.ContentResolver;
import android.content.ContentValues;
-import android.content.IContentProvider;
import android.content.OperationApplicationException;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
@@ -32,80 +30,86 @@ public class ShadowContentProviderClient {
private ContentProvider provider;
@Implementation(minSdk = JELLY_BEAN_MR1)
- public Bundle call(String method, String arg, Bundle extras) throws RemoteException {
+ protected Bundle call(String method, String arg, Bundle extras) throws RemoteException {
return provider.call(method, arg, extras);
}
@Implementation
- public String getType(Uri uri) throws RemoteException {
+ protected String getType(Uri uri) throws RemoteException {
return provider.getType(uri);
}
@Implementation
- public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
+ protected String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
return provider.getStreamTypes(uri, mimeTypeFilter);
}
@Implementation
- public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) throws RemoteException {
+ protected Cursor query(
+ Uri url, String[] projection, String selection, String[] selectionArgs, String sortOrder)
+ throws RemoteException {
return provider.query(url, projection, selection, selectionArgs, sortOrder);
}
@Implementation
- public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
- String sortOrder, CancellationSignal cancellationSignal) throws RemoteException {
+ protected Cursor query(
+ Uri url,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
+ String sortOrder,
+ CancellationSignal cancellationSignal)
+ throws RemoteException {
return provider.query(url, projection, selection, selectionArgs, sortOrder, cancellationSignal);
}
@Implementation
- public Uri insert(Uri url, ContentValues initialValues) throws RemoteException {
+ protected Uri insert(Uri url, ContentValues initialValues) throws RemoteException {
return provider.insert(url, initialValues);
}
@Implementation
- public int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException {
+ protected int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException {
return provider.bulkInsert(url, initialValues);
}
@Implementation
- public int delete(Uri url, String selection, String[] selectionArgs)
- throws RemoteException {
+ protected int delete(Uri url, String selection, String[] selectionArgs) throws RemoteException {
return provider.delete(url, selection, selectionArgs);
}
@Implementation
- public int update(Uri url, ContentValues values, String selection, String[] selectionArgs)
+ protected int update(Uri url, ContentValues values, String selection, String[] selectionArgs)
throws RemoteException {
return provider.update(url, values, selection, selectionArgs);
}
@Implementation
- public ParcelFileDescriptor openFile(Uri url, String mode)
+ protected ParcelFileDescriptor openFile(Uri url, String mode)
throws RemoteException, FileNotFoundException {
return provider.openFile(url, mode);
}
@Implementation
- public AssetFileDescriptor openAssetFile(Uri url, String mode)
+ protected AssetFileDescriptor openAssetFile(Uri url, String mode)
throws RemoteException, FileNotFoundException {
return provider.openAssetFile(url, mode);
}
@Implementation
- public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
- String mimeType, Bundle opts) throws RemoteException, FileNotFoundException {
+ protected final AssetFileDescriptor openTypedAssetFileDescriptor(
+ Uri uri, String mimeType, Bundle opts) throws RemoteException, FileNotFoundException {
return provider.openTypedAssetFile(uri, mimeType, opts);
}
@Implementation
- public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
+ protected ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws RemoteException, OperationApplicationException {
return provider.applyBatch(operations);
}
@Implementation
- public boolean release() {
+ protected boolean release() {
synchronized (this) {
if (released) {
throw new IllegalStateException("Already released");
@@ -116,7 +120,7 @@ public class ShadowContentProviderClient {
}
@Implementation
- public ContentProvider getLocalContentProvider() {
+ protected ContentProvider getLocalContentProvider() {
return ContentProvider.coerceToLocalContentProvider(provider.getIContentProvider());
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProviderResult.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProviderResult.java
index fa6db38ac..baf44dd13 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProviderResult.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentProviderResult.java
@@ -12,7 +12,7 @@ public class ShadowContentProviderResult {
@RealObject ContentProviderResult realResult;
@Implementation
- public void __constructor__(Uri uri)
+ protected void __constructor__(Uri uri)
throws SecurityException, NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field field = realResult.getClass().getField("uri");
@@ -21,7 +21,7 @@ public class ShadowContentProviderResult {
}
@Implementation
- public void __constructor__(int count)
+ protected void __constructor__(int count)
throws SecurityException, NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field field = realResult.getClass().getField("count");
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentResolver.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentResolver.java
index e90aae50f..1e6bd0c65 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentResolver.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentResolver.java
@@ -51,7 +51,6 @@ import org.robolectric.util.ReflectionHelpers.ClassParameter;
@SuppressLint("NewApi")
public class ShadowContentResolver {
private int nextDatabaseIdForInserts;
- private int nextDatabaseIdForUpdates = -1;
@RealObject ContentResolver realContentResolver;
@@ -145,7 +144,7 @@ public class ShadowContentResolver {
}
@Implementation
- public final InputStream openInputStream(final Uri uri) {
+ protected final InputStream openInputStream(final Uri uri) {
InputStream inputStream = inputStreamMap.get(uri);
if (inputStream != null) {
return inputStream;
@@ -155,7 +154,7 @@ public class ShadowContentResolver {
}
@Implementation
- public final OutputStream openOutputStream(final Uri uri) {
+ protected final OutputStream openOutputStream(final Uri uri) {
OutputStream outputStream = outputStreamMap.get(uri);
if (outputStream != null) {
return outputStream;
@@ -174,18 +173,18 @@ public class ShadowContentResolver {
}
/**
- * If a {@link ContentProvider} is registered for the given {@link Uri}, its
- * {@link ContentProvider#insert(Uri, ContentValues)} method will be invoked.
+ * If a {@link ContentProvider} is registered for the given {@link Uri}, its {@link
+ * ContentProvider#insert(Uri, ContentValues)} method will be invoked.
*
- * Tests can verify that this method was called using {@link #getStatements()} or
- * {@link #getInsertStatements()}.
+ * <p>Tests can verify that this method was called using {@link #getStatements()} or {@link
+ * #getInsertStatements()}.
*
- * If no appropriate {@link ContentProvider} is found, no action will be taken and
- * a {@link Uri} including the incremented value set with
- * {@link #setNextDatabaseIdForInserts(int)} will returned.
+ * <p>If no appropriate {@link ContentProvider} is found, no action will be taken and a {@link
+ * Uri} including the incremented value set with {@link #setNextDatabaseIdForInserts(int)} will
+ * returned.
*/
@Implementation
- public final Uri insert(Uri url, ContentValues values) {
+ protected final Uri insert(Uri url, ContentValues values) {
ContentProvider provider = getProvider(url);
ContentValues valuesCopy = (values == null) ? null : new ContentValues(values);
InsertStatement insertStatement = new InsertStatement(url, provider, valuesCopy);
@@ -206,14 +205,11 @@ public class ShadowContentResolver {
* Tests can verify that this method was called using {@link #getStatements()} or
* {@link #getUpdateStatements()}.
*
- * If no appropriate {@link ContentProvider} is found, no action will be taken and
- * the value set with {@link #setNextDatabaseIdForUpdates(int)} will be incremented and returned.
- *
- * *Note:* the return value in this case will be changed to {@code 1} in a future release of
- * Robolectric.
+ * @return If no appropriate {@link ContentProvider} is found, no action will be taken and 1 will
+ * be returned.
*/
@Implementation
- public int update(Uri uri, ContentValues values, String where, String[] selectionArgs) {
+ protected int update(Uri uri, ContentValues values, String where, String[] selectionArgs) {
ContentProvider provider = getProvider(uri);
ContentValues valuesCopy = (values == null) ? null : new ContentValues(values);
UpdateStatement updateStatement =
@@ -224,12 +220,12 @@ public class ShadowContentResolver {
if (provider != null) {
return provider.update(uri, values, where, selectionArgs);
} else {
- return nextDatabaseIdForUpdates == -1 ? 1 : ++nextDatabaseIdForUpdates;
+ return 1;
}
}
@Implementation
- public final Cursor query(
+ protected final Cursor query(
Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
ContentProvider provider = getProvider(uri);
if (provider != null) {
@@ -246,7 +242,7 @@ public class ShadowContentResolver {
}
@Implementation
- public Cursor query(
+ protected Cursor query(
Uri uri,
String[] projection,
String selection,
@@ -269,7 +265,7 @@ public class ShadowContentResolver {
}
@Implementation
- public String getType(Uri uri) {
+ protected String getType(Uri uri) {
ContentProvider provider = getProvider(uri);
if (provider != null) {
return provider.getType(uri);
@@ -279,7 +275,7 @@ public class ShadowContentResolver {
}
@Implementation
- public Bundle call(Uri uri, String method, String arg, Bundle extras) {
+ protected Bundle call(Uri uri, String method, String arg, Bundle extras) {
ContentProvider cp = getProvider(uri);
if (cp != null) {
return cp.call(method, arg, extras);
@@ -289,7 +285,7 @@ public class ShadowContentResolver {
}
@Implementation
- public final ContentProviderClient acquireContentProviderClient(String name) {
+ protected final ContentProviderClient acquireContentProviderClient(String name) {
ContentProvider provider = getProvider(name);
if (provider == null) {
return null;
@@ -298,7 +294,7 @@ public class ShadowContentResolver {
}
@Implementation
- public final ContentProviderClient acquireContentProviderClient(Uri uri) {
+ protected final ContentProviderClient acquireContentProviderClient(Uri uri) {
ContentProvider provider = getProvider(uri);
if (provider == null) {
return null;
@@ -307,7 +303,7 @@ public class ShadowContentResolver {
}
@Implementation
- public final ContentProviderClient acquireUnstableContentProviderClient(String name) {
+ protected final ContentProviderClient acquireUnstableContentProviderClient(String name) {
ContentProvider provider = getProvider(name);
if (provider == null) {
return null;
@@ -316,7 +312,7 @@ public class ShadowContentResolver {
}
@Implementation
- public final ContentProviderClient acquireUnstableContentProviderClient(Uri uri) {
+ protected final ContentProviderClient acquireUnstableContentProviderClient(Uri uri) {
ContentProvider provider = getProvider(uri);
if (provider == null) {
return null;
@@ -337,17 +333,17 @@ public class ShadowContentResolver {
}
@Implementation
- public final IContentProvider acquireProvider(String name) {
+ protected final IContentProvider acquireProvider(String name) {
return acquireUnstableProvider(name);
}
@Implementation
- public final IContentProvider acquireProvider(Uri uri) {
+ protected final IContentProvider acquireProvider(Uri uri) {
return acquireUnstableProvider(uri);
}
@Implementation
- public final IContentProvider acquireUnstableProvider(String name) {
+ protected final IContentProvider acquireUnstableProvider(String name) {
ContentProvider cp = getProvider(name);
if (cp != null) {
return cp.getIContentProvider();
@@ -356,7 +352,7 @@ public class ShadowContentResolver {
}
@Implementation
- public final IContentProvider acquireUnstableProvider(Uri uri) {
+ protected final IContentProvider acquireUnstableProvider(Uri uri) {
ContentProvider cp = getProvider(uri);
if (cp != null) {
return cp.getIContentProvider();
@@ -365,17 +361,17 @@ public class ShadowContentResolver {
}
/**
- * If a {@link ContentProvider} is registered for the given {@link Uri}, its
- * {@link ContentProvider#delete(Uri, String, String[])} method will be invoked.
+ * If a {@link ContentProvider} is registered for the given {@link Uri}, its {@link
+ * ContentProvider#delete(Uri, String, String[])} method will be invoked.
*
- * Tests can verify that this method was called using {@link #getDeleteStatements()}
- * or {@link #getDeletedUris()}.
+ * <p>Tests can verify that this method was called using {@link #getDeleteStatements()} or {@link
+ * #getDeletedUris()}.
*
- * If no appropriate {@link ContentProvider} is found, no action will be taken and
- * {@code 1} will be returned.
+ * <p>If no appropriate {@link ContentProvider} is found, no action will be taken and {@code 1}
+ * will be returned.
*/
@Implementation
- public final int delete(Uri url, String where, String[] selectionArgs) {
+ protected final int delete(Uri url, String where, String[] selectionArgs) {
ContentProvider provider = getProvider(url);
DeleteStatement deleteStatement = new DeleteStatement(url, provider, where, selectionArgs);
@@ -390,17 +386,17 @@ public class ShadowContentResolver {
}
/**
- * If a {@link ContentProvider} is registered for the given {@link Uri}, its
- * {@link ContentProvider#bulkInsert(Uri, ContentValues[])} method will be invoked.
+ * If a {@link ContentProvider} is registered for the given {@link Uri}, its {@link
+ * ContentProvider#bulkInsert(Uri, ContentValues[])} method will be invoked.
*
- * Tests can verify that this method was called using {@link #getStatements()} or
- * {@link #getInsertStatements()}.
+ * <p>Tests can verify that this method was called using {@link #getStatements()} or {@link
+ * #getInsertStatements()}.
*
- * If no appropriate {@link ContentProvider} is found, no action will be taken and
- * the number of rows in {@code values} will be returned.
+ * <p>If no appropriate {@link ContentProvider} is found, no action will be taken and the number
+ * of rows in {@code values} will be returned.
*/
@Implementation
- public final int bulkInsert(Uri url, ContentValues[] values) {
+ protected final int bulkInsert(Uri url, ContentValues[] values) {
ContentProvider provider = getProvider(url);
InsertStatement insertStatement = new InsertStatement(url, provider, values);
@@ -415,7 +411,7 @@ public class ShadowContentResolver {
}
@Implementation
- public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
+ protected void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
notifiedUris.add(new NotifiedUri(uri, observer, syncToNetwork));
for (ContentObserverEntry entry : contentObservers) {
@@ -429,12 +425,12 @@ public class ShadowContentResolver {
}
@Implementation
- public void notifyChange(Uri uri, ContentObserver observer) {
+ protected void notifyChange(Uri uri, ContentObserver observer) {
notifyChange(uri, observer, false);
}
@Implementation
- public ContentProviderResult[] applyBatch(
+ protected ContentProviderResult[] applyBatch(
String authority, ArrayList<ContentProviderOperation> operations)
throws OperationApplicationException {
ContentProvider provider = getProvider(authority);
@@ -447,7 +443,7 @@ public class ShadowContentResolver {
}
@Implementation
- public static void requestSync(Account account, String authority, Bundle extras) {
+ protected static void requestSync(Account account, String authority, Bundle extras) {
validateSyncExtrasBundle(extras);
Status status = getStatus(account, authority, true);
status.syncRequests++;
@@ -455,7 +451,7 @@ public class ShadowContentResolver {
}
@Implementation
- public static void cancelSync(Account account, String authority) {
+ protected static void cancelSync(Account account, String authority) {
Status status = getStatus(account, authority);
if (status != null) {
status.syncRequests = 0;
@@ -470,34 +466,34 @@ public class ShadowContentResolver {
}
@Implementation
- public static boolean isSyncActive(Account account, String authority) {
+ protected static boolean isSyncActive(Account account, String authority) {
ShadowContentResolver.Status status = getStatus(account, authority);
// TODO: this means a sync is *perpetually* active after one request
return status != null && status.syncRequests > 0;
}
@Implementation
- public static void setIsSyncable(Account account, String authority, int syncable) {
+ protected static void setIsSyncable(Account account, String authority, int syncable) {
getStatus(account, authority, true).state = syncable;
}
@Implementation
- public static int getIsSyncable(Account account, String authority) {
+ protected static int getIsSyncable(Account account, String authority) {
return getStatus(account, authority, true).state;
}
@Implementation
- public static boolean getSyncAutomatically(Account account, String authority) {
+ protected static boolean getSyncAutomatically(Account account, String authority) {
return getStatus(account, authority, true).syncAutomatically;
}
@Implementation
- public static void setSyncAutomatically(Account account, String authority, boolean sync) {
+ protected static void setSyncAutomatically(Account account, String authority, boolean sync) {
getStatus(account, authority, true).syncAutomatically = sync;
}
@Implementation
- public static void addPeriodicSync(
+ protected static void addPeriodicSync(
Account account, String authority, Bundle extras, long pollFrequency) {
validateSyncExtrasBundle(extras);
removePeriodicSync(account, authority, extras);
@@ -507,7 +503,7 @@ public class ShadowContentResolver {
}
@Implementation
- public static void removePeriodicSync(Account account, String authority, Bundle extras) {
+ protected static void removePeriodicSync(Account account, String authority, Bundle extras) {
validateSyncExtrasBundle(extras);
Status status = getStatus(account, authority);
if (status != null) {
@@ -521,12 +517,12 @@ public class ShadowContentResolver {
}
@Implementation
- public static List<PeriodicSync> getPeriodicSyncs(Account account, String authority) {
+ protected static List<PeriodicSync> getPeriodicSyncs(Account account, String authority) {
return getStatus(account, authority, true).syncs;
}
@Implementation
- public static void validateSyncExtrasBundle(Bundle extras) {
+ protected static void validateSyncExtrasBundle(Bundle extras) {
for (String key : extras.keySet()) {
Object value = extras.get(key);
if (value == null
@@ -545,17 +541,17 @@ public class ShadowContentResolver {
}
@Implementation
- public static void setMasterSyncAutomatically(boolean sync) {
+ protected static void setMasterSyncAutomatically(boolean sync) {
masterSyncAutomatically = sync;
}
@Implementation
- public static boolean getMasterSyncAutomatically() {
+ protected static boolean getMasterSyncAutomatically() {
return masterSyncAutomatically;
}
@Implementation(minSdk = KITKAT)
- public void takePersistableUriPermission(@NonNull Uri uri, int modeFlags) {
+ protected void takePersistableUriPermission(@NonNull Uri uri, int modeFlags) {
Objects.requireNonNull(uri, "uri may not be null");
modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
@@ -583,7 +579,7 @@ public class ShadowContentResolver {
}
@Implementation(minSdk = KITKAT)
- public void releasePersistableUriPermission(@NonNull Uri uri, int modeFlags) {
+ protected void releasePersistableUriPermission(@NonNull Uri uri, int modeFlags) {
Objects.requireNonNull(uri, "uri may not be null");
modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
@@ -617,7 +613,8 @@ public class ShadowContentResolver {
}
@Implementation(minSdk = KITKAT)
- public @NonNull List<UriPermission> getPersistedUriPermissions() {
+ @NonNull
+ protected List<UriPermission> getPersistedUriPermissions() {
return uriPermissions;
}
@@ -703,21 +700,6 @@ public class ShadowContentResolver {
}
/**
- * Set the value to be returned by
- * {@link ContentResolver#update(Uri, ContentValues, String, String[])} when no appropriate
- * {@link ContentProvider} can be found.
- *
- * @param nextId the number of rows to return
- * @deprecated This method will be removed in Robolectric 3.5. Instead, {@code 1} will be
- * returned.
- */
- @Deprecated
- @SuppressWarnings({"unused", "WeakerAccess"})
- public void setNextDatabaseIdForUpdates(int nextId) {
- nextDatabaseIdForUpdates = nextId;
- }
-
- /**
* Returns the list of {@link InsertStatement}s, {@link UpdateStatement}s, and
* {@link DeleteStatement}s invoked on this {@link ContentResolver}.
*
@@ -789,7 +771,7 @@ public class ShadowContentResolver {
}
@Implementation
- public void registerContentObserver(
+ protected void registerContentObserver(
Uri uri, boolean notifyForDescendents, ContentObserver observer) {
if (uri == null || observer == null) {
throw new NullPointerException();
@@ -798,13 +780,13 @@ public class ShadowContentResolver {
}
@Implementation(minSdk = JELLY_BEAN_MR1)
- public void registerContentObserver(
+ protected void registerContentObserver(
Uri uri, boolean notifyForDescendents, ContentObserver observer, int userHandle) {
registerContentObserver(uri, notifyForDescendents, observer);
}
@Implementation
- public void unregisterContentObserver(ContentObserver observer) {
+ protected void unregisterContentObserver(ContentObserver observer) {
synchronized (contentObservers) {
for (ContentObserverEntry entry : contentObservers) {
if (entry.observer == observer) {
@@ -824,12 +806,6 @@ public class ShadowContentResolver {
ShadowContentResolver.syncAdapterTypes = syncAdapterTypes;
}
- /** @deprecated Do not use this method. */
- @Deprecated
- public void clearContentObservers() {
- contentObservers.clear();
- }
-
/**
* Returns the content observers registered for updates under the given URI.
*
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentUris.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentUris.java
index dc04fe2bb..d0308826f 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentUris.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContentUris.java
@@ -9,12 +9,12 @@ import org.robolectric.annotation.Implements;
public class ShadowContentUris {
@Implementation
- public static Uri withAppendedId(Uri contentUri, long id) {
+ protected static Uri withAppendedId(Uri contentUri, long id) {
return Uri.withAppendedPath(contentUri, String.valueOf(id));
}
@Implementation
- public static long parseId(Uri contentUri) {
+ protected static long parseId(Uri contentUri) {
if (!contentUri.isHierarchical()) {
throw new UnsupportedOperationException();
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContextImpl.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContextImpl.java
index d964c6897..5023cbaf0 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContextImpl.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContextImpl.java
@@ -51,7 +51,7 @@ public class ShadowContextImpl {
@Implementation
@Nullable
- public Object getSystemService(String name) {
+ protected Object getSystemService(String name) {
if (removedSystemServices.contains(name)) {
return null;
}
@@ -78,7 +78,7 @@ public class ShadowContextImpl {
}
@Implementation
- public void startIntentSender(
+ protected void startIntentSender(
IntentSender intent,
Intent fillInIntent,
int flagsMask,
@@ -90,22 +90,22 @@ public class ShadowContextImpl {
}
@Implementation
- public ClassLoader getClassLoader() {
+ protected ClassLoader getClassLoader() {
return this.getClass().getClassLoader();
}
@Implementation
- public int checkCallingPermission(String permission) {
+ protected int checkCallingPermission(String permission) {
return checkPermission(permission, -1, -1);
}
@Implementation
- public int checkCallingOrSelfPermission(String permission) {
+ protected int checkCallingOrSelfPermission(String permission) {
return checkPermission(permission, -1, -1);
}
@Implementation
- public ContentResolver getContentResolver() {
+ protected ContentResolver getContentResolver() {
if (contentResolver == null) {
contentResolver =
new ContentResolver(realContextImpl) {
@@ -137,24 +137,24 @@ public class ShadowContextImpl {
}
@Implementation
- public void sendBroadcast(Intent intent) {
+ protected void sendBroadcast(Intent intent) {
getShadowInstrumentation().sendBroadcastWithPermission(intent, null, realContextImpl);
}
@Implementation
- public void sendBroadcast(Intent intent, String receiverPermission) {
+ protected void sendBroadcast(Intent intent, String receiverPermission) {
getShadowInstrumentation()
.sendBroadcastWithPermission(intent, receiverPermission, realContextImpl);
}
@Implementation
- public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
+ protected void sendOrderedBroadcast(Intent intent, String receiverPermission) {
getShadowInstrumentation()
.sendOrderedBroadcastWithPermission(intent, receiverPermission, realContextImpl);
}
@Implementation
- public void sendOrderedBroadcast(
+ protected void sendOrderedBroadcast(
Intent intent,
String receiverPermission,
BroadcastReceiver resultReceiver,
@@ -175,22 +175,22 @@ public class ShadowContextImpl {
}
@Implementation
- public void sendStickyBroadcast(Intent intent) {
+ protected void sendStickyBroadcast(Intent intent) {
getShadowInstrumentation().sendStickyBroadcast(intent, realContextImpl);
}
@Implementation
- public int checkPermission(String permission, int pid, int uid) {
+ protected int checkPermission(String permission, int pid, int uid) {
return getShadowInstrumentation().checkPermission(permission, pid, uid);
}
@Implementation
- public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ protected Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return getShadowInstrumentation().registerReceiver(receiver, filter, realContextImpl);
}
@Implementation
- public Intent registerReceiver(
+ protected Intent registerReceiver(
BroadcastReceiver receiver,
IntentFilter filter,
String broadcastPermission,
@@ -200,7 +200,7 @@ public class ShadowContextImpl {
}
@Implementation(minSdk = JELLY_BEAN_MR1)
- public Intent registerReceiverAsUser(
+ protected Intent registerReceiverAsUser(
BroadcastReceiver receiver,
UserHandle user,
IntentFilter filter,
@@ -212,27 +212,27 @@ public class ShadowContextImpl {
}
@Implementation
- public void unregisterReceiver(BroadcastReceiver broadcastReceiver) {
+ protected void unregisterReceiver(BroadcastReceiver broadcastReceiver) {
getShadowInstrumentation().unregisterReceiver(broadcastReceiver);
}
@Implementation
- public ComponentName startService(Intent service) {
+ protected ComponentName startService(Intent service) {
return getShadowInstrumentation().startService(service);
}
@Implementation(minSdk = O)
- public ComponentName startForegroundService(Intent service) {
+ protected ComponentName startForegroundService(Intent service) {
return getShadowInstrumentation().startService(service);
}
@Implementation
- public boolean stopService(Intent name) {
+ protected boolean stopService(Intent name) {
return getShadowInstrumentation().stopService(name);
}
@Implementation
- public boolean bindService(Intent intent, final ServiceConnection serviceConnection, int i) {
+ protected boolean bindService(Intent intent, final ServiceConnection serviceConnection, int i) {
return getShadowInstrumentation().bindService(intent, serviceConnection, i);
}
@@ -244,27 +244,27 @@ public class ShadowContextImpl {
}
@Implementation
- public void unbindService(final ServiceConnection serviceConnection) {
+ protected void unbindService(final ServiceConnection serviceConnection) {
getShadowInstrumentation().unbindService(serviceConnection);
}
@Implementation(minSdk = JELLY_BEAN_MR1)
- public int getUserId() {
+ protected int getUserId() {
return 0;
}
@Implementation
- public File getExternalCacheDir() {
+ protected File getExternalCacheDir() {
return Environment.getExternalStorageDirectory();
}
@Implementation(maxSdk = JELLY_BEAN_MR2)
- public File getExternalFilesDir(String type) {
+ protected File getExternalFilesDir(String type) {
return Environment.getExternalStoragePublicDirectory(type);
}
@Implementation(minSdk = KITKAT)
- public File[] getExternalFilesDirs(String type) {
+ protected File[] getExternalFilesDirs(String type) {
return new File[] {Environment.getExternalStoragePublicDirectory(type)};
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCookieManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCookieManager.java
index b4422fd99..a44ecf519 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCookieManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCookieManager.java
@@ -17,7 +17,7 @@ public class ShadowCookieManager {
}
@Implementation
- public static CookieManager getInstance() {
+ protected static CookieManager getInstance() {
if (cookieManager == null) {
cookieManager = new RoboCookieManager();
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCookieSyncManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCookieSyncManager.java
index 7d8cae343..7bfe48d2f 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCookieSyncManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCookieSyncManager.java
@@ -12,7 +12,7 @@ public class ShadowCookieSyncManager extends ShadowWebSyncManager {
private static CookieSyncManager sRef;
@Implementation
- public static synchronized CookieSyncManager createInstance(Context ctx) {
+ protected static synchronized CookieSyncManager createInstance(Context ctx) {
if (sRef == null) {
sRef = Shadow.newInstanceOf(CookieSyncManager.class);
}
@@ -20,7 +20,7 @@ public class ShadowCookieSyncManager extends ShadowWebSyncManager {
}
@Implementation
- public static CookieSyncManager getInstance() {
+ protected static CookieSyncManager getInstance() {
if (sRef == null) {
throw new IllegalStateException("createInstance must be called first");
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCornerPathEffect.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCornerPathEffect.java
index d28e1e6e3..3e4bf8ca2 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCornerPathEffect.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCornerPathEffect.java
@@ -10,7 +10,7 @@ public class ShadowCornerPathEffect {
private float radius;
@Implementation
- public void __constructor__(float radius) {
+ protected void __constructor__(float radius) {
this.radius = radius;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCountDownTimer.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCountDownTimer.java
index c01f1ae01..07d58d7f9 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCountDownTimer.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCountDownTimer.java
@@ -14,20 +14,20 @@ public class ShadowCountDownTimer {
@RealObject CountDownTimer countDownTimer;
@Implementation
- public void __constructor__(long millisInFuture, long countDownInterval) {
+ protected void __constructor__(long millisInFuture, long countDownInterval) {
this.countDownInterval = countDownInterval;
this.millisInFuture = millisInFuture;
this.started = false;
}
@Implementation
- public final synchronized CountDownTimer start() {
+ protected final synchronized CountDownTimer start() {
started = true;
return countDownTimer;
}
@Implementation
- public final void cancel() {
+ protected final void cancel() {
started = false;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCursorWindow.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCursorWindow.java
index edd311ef3..996019f38 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCursorWindow.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCursorWindow.java
@@ -23,27 +23,27 @@ public class ShadowCursorWindow {
private static final WindowData WINDOW_DATA = new WindowData();
@Implementation
- public static Number nativeCreate(String name, int cursorWindowSize) {
+ protected static Number nativeCreate(String name, int cursorWindowSize) {
return castNativePtr(WINDOW_DATA.create(name, cursorWindowSize));
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static void nativeDispose(int windowPtr) {
+ protected static void nativeDispose(int windowPtr) {
nativeDispose((long) windowPtr);
}
@Implementation(minSdk = LOLLIPOP)
- public static void nativeDispose(long windowPtr) {
+ protected static void nativeDispose(long windowPtr) {
WINDOW_DATA.close(windowPtr);
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static byte[] nativeGetBlob(int windowPtr, int row, int column) {
+ protected static byte[] nativeGetBlob(int windowPtr, int row, int column) {
return nativeGetBlob((long) windowPtr, row, column);
}
@Implementation(minSdk = LOLLIPOP)
- public static byte[] nativeGetBlob(long windowPtr, int row, int column) {
+ protected static byte[] nativeGetBlob(long windowPtr, int row, int column) {
Value value = WINDOW_DATA.get(windowPtr).value(row, column);
switch (value.type) {
@@ -61,12 +61,12 @@ public class ShadowCursorWindow {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static String nativeGetString(int windowPtr, int row, int column) {
+ protected static String nativeGetString(int windowPtr, int row, int column) {
return nativeGetString((long) windowPtr, row, column);
}
@Implementation(minSdk = LOLLIPOP)
- public static String nativeGetString(long windowPtr, int row, int column) {
+ protected static String nativeGetString(long windowPtr, int row, int column) {
Value val = WINDOW_DATA.get(windowPtr).value(row, column);
if (val.type == Cursor.FIELD_TYPE_BLOB) {
throw new android.database.sqlite.SQLiteException("Getting string when column is blob. Row " + row + ", col " + column);
@@ -76,132 +76,132 @@ public class ShadowCursorWindow {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static long nativeGetLong(int windowPtr, int row, int column) {
+ protected static long nativeGetLong(int windowPtr, int row, int column) {
return nativeGetLong((long) windowPtr, row, column);
}
@Implementation(minSdk = LOLLIPOP)
- public static long nativeGetLong(long windowPtr, int row, int column) {
+ protected static long nativeGetLong(long windowPtr, int row, int column) {
return nativeGetNumber(windowPtr, row, column).longValue();
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static double nativeGetDouble(int windowPtr, int row, int column) {
+ protected static double nativeGetDouble(int windowPtr, int row, int column) {
return nativeGetDouble((long) windowPtr, row, column);
}
@Implementation(minSdk = LOLLIPOP)
- public static double nativeGetDouble(long windowPtr, int row, int column) {
+ protected static double nativeGetDouble(long windowPtr, int row, int column) {
return nativeGetNumber(windowPtr, row, column).doubleValue();
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static int nativeGetType(int windowPtr, int row, int column) {
+ protected static int nativeGetType(int windowPtr, int row, int column) {
return nativeGetType((long) windowPtr, row, column);
}
@Implementation(minSdk = LOLLIPOP)
- public static int nativeGetType(long windowPtr, int row, int column) {
+ protected static int nativeGetType(long windowPtr, int row, int column) {
return WINDOW_DATA.get(windowPtr).value(row, column).type;
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static void nativeClear(int windowPtr) {
+ protected static void nativeClear(int windowPtr) {
nativeClear((long) windowPtr);
}
@Implementation(minSdk = LOLLIPOP)
- public static void nativeClear(long windowPtr) {
+ protected static void nativeClear(long windowPtr) {
WINDOW_DATA.clear(windowPtr);
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static int nativeGetNumRows(int windowPtr) {
+ protected static int nativeGetNumRows(int windowPtr) {
return nativeGetNumRows((long) windowPtr);
}
@Implementation(minSdk = LOLLIPOP)
- public static int nativeGetNumRows(long windowPtr) {
+ protected static int nativeGetNumRows(long windowPtr) {
return WINDOW_DATA.get(windowPtr).numRows();
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static boolean nativePutBlob(int windowPtr, byte[] value, int row, int column) {
+ protected static boolean nativePutBlob(int windowPtr, byte[] value, int row, int column) {
return nativePutBlob((long) windowPtr, value, row, column);
}
@Implementation(minSdk = LOLLIPOP)
- public static boolean nativePutBlob(long windowPtr, byte[] value, int row, int column) {
+ protected static boolean nativePutBlob(long windowPtr, byte[] value, int row, int column) {
return WINDOW_DATA.get(windowPtr).putValue(new Value(value, Cursor.FIELD_TYPE_BLOB), row, column);
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static boolean nativePutString(int windowPtr, String value, int row, int column) {
+ protected static boolean nativePutString(int windowPtr, String value, int row, int column) {
return nativePutString((long) windowPtr, value, row, column);
}
@Implementation(minSdk = LOLLIPOP)
- public static boolean nativePutString(long windowPtr, String value, int row, int column) {
+ protected static boolean nativePutString(long windowPtr, String value, int row, int column) {
return WINDOW_DATA.get(windowPtr).putValue(new Value(value, Cursor.FIELD_TYPE_STRING), row, column);
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static boolean nativePutLong(int windowPtr, long value, int row, int column) {
+ protected static boolean nativePutLong(int windowPtr, long value, int row, int column) {
return nativePutLong((long) windowPtr, value, row, column);
}
@Implementation(minSdk = LOLLIPOP)
- public static boolean nativePutLong(long windowPtr, long value, int row, int column) {
+ protected static boolean nativePutLong(long windowPtr, long value, int row, int column) {
return WINDOW_DATA.get(windowPtr).putValue(new Value(value, Cursor.FIELD_TYPE_INTEGER), row, column);
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static boolean nativePutDouble(int windowPtr, double value, int row, int column) {
+ protected static boolean nativePutDouble(int windowPtr, double value, int row, int column) {
return nativePutDouble((long) windowPtr, value, row, column);
}
@Implementation(minSdk = LOLLIPOP)
- public static boolean nativePutDouble(long windowPtr, double value, int row, int column) {
+ protected static boolean nativePutDouble(long windowPtr, double value, int row, int column) {
return WINDOW_DATA.get(windowPtr).putValue(new Value(value, Cursor.FIELD_TYPE_FLOAT), row, column);
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static boolean nativePutNull(int windowPtr, int row, int column) {
+ protected static boolean nativePutNull(int windowPtr, int row, int column) {
return nativePutNull((long) windowPtr, row, column);
}
@Implementation(minSdk = LOLLIPOP)
- public static boolean nativePutNull(long windowPtr, int row, int column) {
+ protected static boolean nativePutNull(long windowPtr, int row, int column) {
return WINDOW_DATA.get(windowPtr).putValue(new Value(null, Cursor.FIELD_TYPE_NULL), row, column);
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static boolean nativeAllocRow(int windowPtr) {
+ protected static boolean nativeAllocRow(int windowPtr) {
return nativeAllocRow((long) windowPtr);
}
@Implementation(minSdk = LOLLIPOP)
- public static boolean nativeAllocRow(long windowPtr) {
+ protected static boolean nativeAllocRow(long windowPtr) {
return WINDOW_DATA.get(windowPtr).allocRow();
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static boolean nativeSetNumColumns(int windowPtr, int columnNum) {
+ protected static boolean nativeSetNumColumns(int windowPtr, int columnNum) {
return nativeSetNumColumns((long) windowPtr, columnNum);
}
@Implementation(minSdk = LOLLIPOP)
- public static boolean nativeSetNumColumns(long windowPtr, int columnNum) {
+ protected static boolean nativeSetNumColumns(long windowPtr, int columnNum) {
return WINDOW_DATA.get(windowPtr).setNumColumns(columnNum);
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static String nativeGetName(int windowPtr) {
+ protected static String nativeGetName(int windowPtr) {
return nativeGetName((long) windowPtr);
}
@Implementation(minSdk = LOLLIPOP)
- public static String nativeGetName(long windowPtr) {
+ protected static String nativeGetName(long windowPtr) {
return WINDOW_DATA.get(windowPtr).getName();
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCursorWrapper.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCursorWrapper.java
index 163e70320..04623f10c 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCursorWrapper.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowCursorWrapper.java
@@ -19,7 +19,7 @@ public class ShadowCursorWrapper implements Cursor {
private Cursor wrappedCursor;
@Implementation
- public void __constructor__(Cursor c) {
+ protected void __constructor__(Cursor c) {
wrappedCursor = c;
}
@@ -229,7 +229,7 @@ public class ShadowCursorWrapper implements Cursor {
}
@Implementation
- public Cursor getWrappedCursor() {
+ protected Cursor getWrappedCursor() {
return wrappedCursor;
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDateFormat.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDateFormat.java
index 5aa9fc8b5..c83020fb2 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDateFormat.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDateFormat.java
@@ -10,17 +10,17 @@ import org.robolectric.annotation.Implements;
public class ShadowDateFormat {
@Implementation
- public static java.text.DateFormat getDateFormat(Context context) {
- return new java.text.SimpleDateFormat("MMM-dd-yyyy", Locale.getDefault());
+ protected static java.text.DateFormat getDateFormat(Context context) {
+ return new java.text.SimpleDateFormat("MMM-dd-yyyy", Locale.ROOT);
}
@Implementation
- public static java.text.DateFormat getLongDateFormat(Context context) {
- return new java.text.SimpleDateFormat("MMMM dd, yyyy", Locale.getDefault());
+ protected static java.text.DateFormat getLongDateFormat(Context context) {
+ return new java.text.SimpleDateFormat("MMMM dd, yyyy", Locale.ROOT);
}
@Implementation
- public static java.text.DateFormat getTimeFormat(Context context) {
- return new java.text.SimpleDateFormat("HH:mm:ss", Locale.getDefault());
+ protected static java.text.DateFormat getTimeFormat(Context context) {
+ return new java.text.SimpleDateFormat("HH:mm:ss", Locale.ROOT);
}
-} \ No newline at end of file
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDatePickerDialog.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDatePickerDialog.java
index 2841f0557..ffa5793ab 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDatePickerDialog.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDatePickerDialog.java
@@ -23,8 +23,13 @@ public class ShadowDatePickerDialog extends ShadowAlertDialog {
private DatePickerDialog.OnDateSetListener callBack;
@Implementation(maxSdk = M)
- public void __constructor__(Context context, int theme, DatePickerDialog.OnDateSetListener callBack,
- int year, int monthOfYear, int dayOfMonth) {
+ protected void __constructor__(
+ Context context,
+ int theme,
+ DatePickerDialog.OnDateSetListener callBack,
+ int year,
+ int monthOfYear,
+ int dayOfMonth) {
this.year = year;
this.monthOfYear = monthOfYear;
this.dayOfMonth = dayOfMonth;
@@ -40,8 +45,14 @@ public class ShadowDatePickerDialog extends ShadowAlertDialog {
}
@Implementation(minSdk = N)
- public void __constructor__(Context context, int theme, DatePickerDialog.OnDateSetListener callBack,
- Calendar calendar, int year, int monthOfYear, int dayOfMonth) {
+ protected void __constructor__(
+ Context context,
+ int theme,
+ DatePickerDialog.OnDateSetListener callBack,
+ Calendar calendar,
+ int year,
+ int monthOfYear,
+ int dayOfMonth) {
this.calendar = calendar;
this.year = year;
this.monthOfYear = monthOfYear;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDebug.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDebug.java
index 92dffe2bf..e7d70a80a 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDebug.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDebug.java
@@ -22,7 +22,7 @@ public class ShadowDebug {
private static String tracingFilename;
@Implementation
- public static void __staticInitializer__() {
+ protected static void __staticInitializer__() {
// Avoid calling Environment.getLegacyExternalStorageDirectory()
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDevicePolicyManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDevicePolicyManager.java
index d7be0c8e1..18b3a57da 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDevicePolicyManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDevicePolicyManager.java
@@ -44,7 +44,6 @@ import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.shadow.api.Shadow;
-/** Shadow for {@link DevicePolicyManager} */
@Implements(DevicePolicyManager.class)
@SuppressLint("NewApi")
public class ShadowDevicePolicyManager {
@@ -58,6 +57,7 @@ public class ShadowDevicePolicyManager {
private ComponentName deviceOwner;
private ComponentName profileOwner;
private List<ComponentName> deviceAdmins = new ArrayList<>();
+ private Map<Integer, String> profileOwnerNamesMap = new HashMap<>();
private List<String> permittedAccessibilityServices = new ArrayList<>();
private List<String> permittedInputMethods = new ArrayList<>();
private Map<String, Bundle> applicationRestrictionsMap = new HashMap<>();
@@ -150,39 +150,39 @@ public class ShadowDevicePolicyManager {
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public boolean isDeviceOwnerApp(String packageName) {
+ protected boolean isDeviceOwnerApp(String packageName) {
return deviceOwner != null && deviceOwner.getPackageName().equals(packageName);
}
@Implementation(minSdk = LOLLIPOP)
- public boolean isProfileOwnerApp(String packageName) {
+ protected boolean isProfileOwnerApp(String packageName) {
return profileOwner != null && profileOwner.getPackageName().equals(packageName);
}
@Implementation
- public boolean isAdminActive(ComponentName who) {
+ protected boolean isAdminActive(ComponentName who) {
return who != null && deviceAdmins.contains(who);
}
@Implementation
- public List<ComponentName> getActiveAdmins() {
+ protected List<ComponentName> getActiveAdmins() {
return deviceAdmins;
}
@Implementation(minSdk = LOLLIPOP)
- public void addUserRestriction(ComponentName admin, String key) {
+ protected void addUserRestriction(ComponentName admin, String key) {
enforceActiveAdmin(admin);
getShadowUserManager().setUserRestriction(Process.myUserHandle(), key, true);
}
@Implementation(minSdk = LOLLIPOP)
- public void clearUserRestriction(ComponentName admin, String key) {
+ protected void clearUserRestriction(ComponentName admin, String key) {
enforceActiveAdmin(admin);
getShadowUserManager().setUserRestriction(Process.myUserHandle(), key, false);
}
@Implementation(minSdk = LOLLIPOP)
- public boolean setApplicationHidden(ComponentName admin, String packageName, boolean hidden) {
+ protected boolean setApplicationHidden(ComponentName admin, String packageName, boolean hidden) {
enforceActiveAdmin(admin);
if (packagesToFailForSetApplicationHidden.contains(packageName)) {
return false;
@@ -207,7 +207,7 @@ public class ShadowDevicePolicyManager {
}
@Implementation(minSdk = LOLLIPOP)
- public boolean isApplicationHidden(ComponentName admin, String packageName) {
+ protected boolean isApplicationHidden(ComponentName admin, String packageName) {
enforceActiveAdmin(admin);
return applicationPackageManager.getApplicationHiddenSettingAsUser(
packageName, Process.myUserHandle());
@@ -219,10 +219,9 @@ public class ShadowDevicePolicyManager {
}
@Implementation(minSdk = LOLLIPOP)
- public int enableSystemApp(ComponentName admin, String packageName) {
+ protected void enableSystemApp(ComponentName admin, String packageName) {
enforceActiveAdmin(admin);
systemAppsEnabled.add(packageName);
- return 1;
}
/** Returns {@code true} if the given {@code packageName} was a system app and was enabled. */
@@ -231,7 +230,7 @@ public class ShadowDevicePolicyManager {
}
@Implementation(minSdk = LOLLIPOP)
- public void setUninstallBlocked(
+ protected void setUninstallBlocked(
ComponentName admin, String packageName, boolean uninstallBlocked) {
enforceActiveAdmin(admin);
if (uninstallBlocked) {
@@ -242,7 +241,7 @@ public class ShadowDevicePolicyManager {
}
@Implementation(minSdk = LOLLIPOP)
- public boolean isUninstallBlocked(ComponentName admin, String packageName) {
+ protected boolean isUninstallBlocked(ComponentName admin, String packageName) {
enforceActiveAdmin(admin);
return uninstallBlockedPackages.contains(packageName);
}
@@ -259,6 +258,15 @@ public class ShadowDevicePolicyManager {
return profileOwner;
}
+ /**
+ * Returns the human-readable name of the profile owner for a user if set using
+ * {@link #setProfileOwnerName}, otherwise `null`.
+ */
+ @Implementation(minSdk = LOLLIPOP)
+ protected String getProfileOwnerNameAsUser(int userId) {
+ return profileOwnerNamesMap.get(userId);
+ }
+
private ShadowUserManager getShadowUserManager() {
return Shadow.extract(context.getSystemService(Context.USER_SERVICE));
}
@@ -283,18 +291,22 @@ public class ShadowDevicePolicyManager {
profileOwner = admin;
}
+ public void setProfileOwnerName(int userId, String name) {
+ profileOwnerNamesMap.put(userId, name);
+ }
+
/** Sets the given {@code componentName} as one of the active admins. */
public void setActiveAdmin(ComponentName componentName) {
deviceAdmins.add(componentName);
}
@Implementation
- public void removeActiveAdmin(ComponentName admin) {
+ protected void removeActiveAdmin(ComponentName admin) {
deviceAdmins.remove(admin);
}
@Implementation(minSdk = LOLLIPOP)
- public void clearProfileOwner(ComponentName admin) {
+ protected void clearProfileOwner(ComponentName admin) {
profileOwner = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
removeActiveAdmin(admin);
@@ -302,7 +314,7 @@ public class ShadowDevicePolicyManager {
}
@Implementation(minSdk = LOLLIPOP)
- public Bundle getApplicationRestrictions(ComponentName admin, String packageName) {
+ protected Bundle getApplicationRestrictions(ComponentName admin, String packageName) {
enforceDeviceOwnerOrProfileOwner(admin);
return getApplicationRestrictions(packageName);
}
@@ -315,7 +327,7 @@ public class ShadowDevicePolicyManager {
}
@Implementation(minSdk = LOLLIPOP)
- public void setApplicationRestrictions(
+ protected void setApplicationRestrictions(
ComponentName admin, String packageName, Bundle applicationRestrictions) {
enforceDeviceOwnerOrProfileOwner(admin);
setApplicationRestrictions(packageName, applicationRestrictions);
@@ -355,7 +367,7 @@ public class ShadowDevicePolicyManager {
}
@Implementation(minSdk = LOLLIPOP)
- public void setAccountManagementDisabled(
+ protected void setAccountManagementDisabled(
ComponentName admin, String accountType, boolean disabled) {
enforceDeviceOwnerOrProfileOwner(admin);
if (disabled) {
@@ -366,7 +378,7 @@ public class ShadowDevicePolicyManager {
}
@Implementation(minSdk = LOLLIPOP)
- public String[] getAccountTypesWithManagementDisabled() {
+ protected String[] getAccountTypesWithManagementDisabled() {
return accountTypesWithManagementDisabled.toArray(new String[0]);
}
@@ -377,7 +389,7 @@ public class ShadowDevicePolicyManager {
* profile owner and device owner since Android O.
*/
@Implementation(minSdk = N)
- public void setOrganizationName(ComponentName admin, @Nullable CharSequence name) {
+ protected void setOrganizationName(ComponentName admin, @Nullable CharSequence name) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
enforceDeviceOwnerOrProfileOwner(admin);
} else {
@@ -430,7 +442,7 @@ public class ShadowDevicePolicyManager {
}
@Implementation(minSdk = N)
- public void setOrganizationColor(ComponentName admin, int color) {
+ protected void setOrganizationColor(ComponentName admin, int color) {
enforceProfileOwner(admin);
organizationColor = color;
}
@@ -447,7 +459,7 @@ public class ShadowDevicePolicyManager {
*/
@Implementation(minSdk = N)
@Nullable
- public CharSequence getOrganizationName(ComponentName admin) {
+ protected CharSequence getOrganizationName(ComponentName admin) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
enforceDeviceOwnerOrProfileOwner(admin);
} else {
@@ -458,19 +470,19 @@ public class ShadowDevicePolicyManager {
}
@Implementation(minSdk = N)
- public int getOrganizationColor(ComponentName admin) {
+ protected int getOrganizationColor(ComponentName admin) {
enforceProfileOwner(admin);
return organizationColor;
}
@Implementation(minSdk = LOLLIPOP)
- public void setAutoTimeRequired(ComponentName admin, boolean required) {
+ protected void setAutoTimeRequired(ComponentName admin, boolean required) {
enforceDeviceOwnerOrProfileOwner(admin);
isAutoTimeRequired = required;
}
@Implementation(minSdk = LOLLIPOP)
- public boolean getAutoTimeRequired() {
+ protected boolean getAutoTimeRequired() {
return isAutoTimeRequired;
}
@@ -483,7 +495,8 @@ public class ShadowDevicePolicyManager {
* set the restriction and return true.
*/
@Implementation(minSdk = LOLLIPOP)
- public boolean setPermittedAccessibilityServices(ComponentName admin, List<String> packageNames) {
+ protected boolean setPermittedAccessibilityServices(
+ ComponentName admin, List<String> packageNames) {
enforceDeviceOwnerOrProfileOwner(admin);
permittedAccessibilityServices = packageNames;
return true;
@@ -491,7 +504,7 @@ public class ShadowDevicePolicyManager {
@Implementation(minSdk = LOLLIPOP)
@Nullable
- public List<String> getPermittedAccessibilityServices(ComponentName admin) {
+ protected List<String> getPermittedAccessibilityServices(ComponentName admin) {
enforceDeviceOwnerOrProfileOwner(admin);
return permittedAccessibilityServices;
}
@@ -505,7 +518,7 @@ public class ShadowDevicePolicyManager {
* restriction and return true.
*/
@Implementation(minSdk = LOLLIPOP)
- public boolean setPermittedInputMethods(ComponentName admin, List<String> packageNames) {
+ protected boolean setPermittedInputMethods(ComponentName admin, List<String> packageNames) {
enforceDeviceOwnerOrProfileOwner(admin);
permittedInputMethods = packageNames;
return true;
@@ -513,7 +526,7 @@ public class ShadowDevicePolicyManager {
@Implementation(minSdk = LOLLIPOP)
@Nullable
- public List<String> getPermittedInputMethods(ComponentName admin) {
+ protected List<String> getPermittedInputMethods(ComponentName admin) {
enforceDeviceOwnerOrProfileOwner(admin);
return permittedInputMethods;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDialog.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDialog.java
index 5be430b9c..fa43cecbe 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDialog.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDialog.java
@@ -58,14 +58,14 @@ public class ShadowDialog {
}
@Implementation
- public void show() {
+ protected void show() {
setLatestDialog(this);
shownDialogs.add(realDialog);
directlyOn(realDialog, Dialog.class).show();
}
@Implementation
- public void dismiss() {
+ protected void dismiss() {
directlyOn(realDialog, Dialog.class).dismiss();
hasBeenDismissed = true;
}
@@ -75,7 +75,7 @@ public class ShadowDialog {
}
@Implementation
- public void setCanceledOnTouchOutside(boolean flag) {
+ protected void setCanceledOnTouchOutside(boolean flag) {
isCancelableOnTouchOutside = flag;
directlyOn(realDialog, Dialog.class).setCanceledOnTouchOutside(flag);
}
@@ -93,7 +93,7 @@ public class ShadowDialog {
}
@Implementation
- public void setOnCancelListener(DialogInterface.OnCancelListener listener) {
+ protected void setOnCancelListener(DialogInterface.OnCancelListener listener) {
this.onCancelListener = listener;
directlyOn(realDialog, Dialog.class).setOnCancelListener(listener);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDiscoverySession.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDiscoverySession.java
index b91c17b17..0fc9de303 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDiscoverySession.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDiscoverySession.java
@@ -6,7 +6,6 @@ import android.net.wifi.aware.DiscoverySession;
import org.robolectric.annotation.Implements;
import org.robolectric.util.ReflectionHelpers;
-/** Shadow for {@link DiscoverySession}. */
@Implements(value = DiscoverySession.class, minSdk = O)
public class ShadowDiscoverySession {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplay.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplay.java
index 30a9bc87f..089e626d7 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplay.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplay.java
@@ -57,14 +57,14 @@ public class ShadowDisplay {
private Integer pixelFormat;
/**
- * If {@link #setScaledDensity(float)} has been called, {@link DisplayMetrics#scaledDensity}
- * will be modified to reflect the value specified. Note that this is not a realistic state.
+ * If {@link #setScaledDensity(float)} has been called, {@link DisplayMetrics#scaledDensity} will
+ * be modified to reflect the value specified. Note that this is not a realistic state.
*
* @deprecated This behavior is deprecated and will be removed in Robolectric 3.7.
*/
@Deprecated
@Implementation
- public void getMetrics(DisplayMetrics outMetrics) {
+ protected void getMetrics(DisplayMetrics outMetrics) {
if (isJB()) {
outMetrics.density = densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
outMetrics.densityDpi = densityDpi;
@@ -82,14 +82,14 @@ public class ShadowDisplay {
}
/**
- * If {@link #setScaledDensity(float)} has been called, {@link DisplayMetrics#scaledDensity}
- * will be modified to reflect the value specified. Note that this is not a realistic state.
+ * If {@link #setScaledDensity(float)} has been called, {@link DisplayMetrics#scaledDensity} will
+ * be modified to reflect the value specified. Note that this is not a realistic state.
*
* @deprecated This behavior is deprecated and will be removed in Robolectric 3.7.
*/
@Deprecated
@Implementation
- public void getRealMetrics(DisplayMetrics outMetrics) {
+ protected void getRealMetrics(DisplayMetrics outMetrics) {
if (isJB()) {
getMetrics(outMetrics);
outMetrics.widthPixels = realWidth;
@@ -109,7 +109,7 @@ public class ShadowDisplay {
*/
@Deprecated
@Implementation
- public int getDisplayId() {
+ protected int getDisplayId() {
return displayId == null
? directlyOn(realObject, Display.class).getDisplayId()
: displayId;
@@ -122,7 +122,7 @@ public class ShadowDisplay {
*/
@Deprecated
@Implementation
- public float getRefreshRate() {
+ protected float getRefreshRate() {
return refreshRate == null
? directlyOn(realObject, Display.class).getRefreshRate()
: refreshRate;
@@ -135,20 +135,20 @@ public class ShadowDisplay {
*/
@Deprecated
@Implementation
- public int getPixelFormat() {
+ protected int getPixelFormat() {
return pixelFormat == null
? directlyOn(realObject, Display.class).getPixelFormat()
: pixelFormat;
}
@Implementation(maxSdk = JELLY_BEAN)
- public void getSizeInternal(Point outSize, boolean doCompat) {
+ protected void getSizeInternal(Point outSize, boolean doCompat) {
outSize.x = width;
outSize.y = height;
}
@Implementation(maxSdk = JELLY_BEAN)
- public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
+ protected void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
int minimum = Math.min(width, height);
int maximum = Math.max(width, height);
outSmallestSize.set(minimum, minimum);
@@ -156,7 +156,7 @@ public class ShadowDisplay {
}
@Implementation(maxSdk = JELLY_BEAN)
- public void getRealSize(Point outSize) {
+ protected void getRealSize(Point outSize) {
outSize.set(realWidth, realHeight);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayListCanvas.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayListCanvas.java
new file mode 100644
index 000000000..5bec276d1
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayListCanvas.java
@@ -0,0 +1,30 @@
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.M;
+import static android.os.Build.VERSION_CODES.N;
+import static android.os.Build.VERSION_CODES.N_MR1;
+import static android.os.Build.VERSION_CODES.O;
+import static android.os.Build.VERSION_CODES.P;
+
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(className = "android.view.DisplayListCanvas", isInAndroidSdk = false, minSdk = M, maxSdk = P)
+public class ShadowDisplayListCanvas extends ShadowCanvas {
+
+ @Implementation(minSdk = O)
+ protected static long nCreateDisplayListCanvas(long node, int width, int height) {
+ return 1;
+ }
+
+ @Config(minSdk = N, maxSdk = N_MR1)
+ protected static long nCreateDisplayListCanvas(int width, int height) {
+ return 1;
+ }
+
+ @Config(maxSdk = M)
+ protected static long nCreateDisplayListCanvas() {
+ return 1;
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDownloadManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDownloadManager.java
index dd086893a..bc272eb1a 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDownloadManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDownloadManager.java
@@ -22,14 +22,14 @@ public class ShadowDownloadManager {
private Map<Long, DownloadManager.Request> requestMap = new TreeMap<>();
@Implementation
- public long enqueue(DownloadManager.Request request) {
+ protected long enqueue(DownloadManager.Request request) {
queueCounter++;
requestMap.put(queueCounter, request);
return queueCounter;
}
@Implementation
- public int remove(long... ids) {
+ protected int remove(long... ids) {
int removeCount = 0;
for (long id : ids) {
if (requestMap.remove(id) != null) {
@@ -40,7 +40,7 @@ public class ShadowDownloadManager {
}
@Implementation
- public Cursor query(DownloadManager.Query query) {
+ protected Cursor query(DownloadManager.Query query) {
ResultCursor result = new ResultCursor();
ShadowQuery shadow = Shadow.extract(query);
long[] ids = shadow.getIds();
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDrawable.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDrawable.java
index d10f4f413..279f29d7a 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDrawable.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDrawable.java
@@ -41,7 +41,7 @@ public class ShadowDrawable {
private boolean wasInvalidated;
@Implementation
- public static Drawable createFromStream(InputStream is, String srcName) {
+ protected static Drawable createFromStream(InputStream is, String srcName) {
if (corruptStreamSources.contains(srcName)) {
return null;
}
@@ -54,8 +54,8 @@ public class ShadowDrawable {
}
@Implementation // todo: this sucks, it's all just so we can detect 9-patches
- public static Drawable createFromResourceStream(Resources res, TypedValue value,
- InputStream is, String srcName, BitmapFactory.Options opts) {
+ protected static Drawable createFromResourceStream(
+ Resources res, TypedValue value, InputStream is, String srcName, BitmapFactory.Options opts) {
if (is == null) {
return null;
}
@@ -86,7 +86,7 @@ public class ShadowDrawable {
}
@Implementation
- public static Drawable createFromPath(String pathName) {
+ protected static Drawable createFromPath(String pathName) {
BitmapDrawable drawable = new BitmapDrawable(ReflectionHelpers.callConstructor(Bitmap.class));
ShadowBitmapDrawable shadowBitmapDrawable = Shadow.extract(drawable);
shadowBitmapDrawable.drawableCreateFromPath = pathName;
@@ -106,12 +106,12 @@ public class ShadowDrawable {
}
@Implementation
- public int getIntrinsicWidth() {
+ protected int getIntrinsicWidth() {
return intrinsicWidth;
}
@Implementation
- public int getIntrinsicHeight() {
+ protected int getIntrinsicHeight() {
return intrinsicHeight;
}
@@ -145,19 +145,19 @@ public class ShadowDrawable {
}
@Implementation
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
this.alpha = alpha;
Shadow.directlyOn(realDrawable, Drawable.class).setAlpha(alpha);
}
@Implementation
- public void invalidateSelf() {
+ protected void invalidateSelf() {
wasInvalidated = true;
Shadow.directlyOn(realDrawable, Drawable.class, "invalidateSelf");
}
@Implementation(minSdk = KITKAT)
- public int getAlpha() {
+ protected int getAlpha() {
return alpha;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowEnvironment.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowEnvironment.java
index ce8801a45..a7f7dd1a8 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowEnvironment.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowEnvironment.java
@@ -34,7 +34,7 @@ public class ShadowEnvironment {
static Path EXTERNAL_FILES_DIR;
@Implementation
- public static String getExternalStorageState() {
+ protected static String getExternalStorageState() {
return externalStorageState;
}
@@ -57,13 +57,13 @@ public class ShadowEnvironment {
}
@Implementation
- public static File getExternalStorageDirectory() {
+ protected static File getExternalStorageDirectory() {
if (!exists(EXTERNAL_CACHE_DIR)) EXTERNAL_CACHE_DIR = RuntimeEnvironment.getTempDirectory().create("external-cache");
return EXTERNAL_CACHE_DIR.toFile();
}
@Implementation
- public static File getExternalStoragePublicDirectory(String type) {
+ protected static File getExternalStoragePublicDirectory(String type) {
if (!exists(EXTERNAL_FILES_DIR)) EXTERNAL_FILES_DIR = RuntimeEnvironment.getTempDirectory().create("external-files");
if (type == null) return EXTERNAL_FILES_DIR.toFile();
Path path = EXTERNAL_FILES_DIR.resolve(type);
@@ -95,13 +95,13 @@ public class ShadowEnvironment {
}
@Implementation
- public static boolean isExternalStorageRemovable() {
+ protected static boolean isExternalStorageRemovable() {
final Boolean exists = STORAGE_REMOVABLE.get(getExternalStorageDirectory());
return exists != null ? exists : false;
}
@Implementation(minSdk = KITKAT)
- public static String getStorageState(File directory) {
+ protected static String getStorageState(File directory) {
Path directoryPath = directory.toPath();
for (Map.Entry<Path, String> entry : storageState.entrySet()) {
if (directoryPath.startsWith(entry.getKey())) {
@@ -112,7 +112,7 @@ public class ShadowEnvironment {
}
@Implementation(minSdk = LOLLIPOP)
- public static String getExternalStorageState(File directory) {
+ protected static String getExternalStorageState(File directory) {
Path directoryPath = directory.toPath();
for (Map.Entry<Path, String> entry : storageState.entrySet()) {
if (directoryPath.startsWith(entry.getKey())) {
@@ -122,21 +122,20 @@ public class ShadowEnvironment {
return null;
}
-
@Implementation(minSdk = LOLLIPOP)
- public static boolean isExternalStorageRemovable(File path) {
+ protected static boolean isExternalStorageRemovable(File path) {
final Boolean exists = STORAGE_REMOVABLE.get(path);
return exists != null ? exists : false;
}
@Implementation(minSdk = LOLLIPOP)
- public static boolean isExternalStorageEmulated(File path) {
+ protected static boolean isExternalStorageEmulated(File path) {
final Boolean emulated = STORAGE_EMULATED.get(path);
return emulated != null ? emulated : false;
}
@Implementation
- public static boolean isExternalStorageEmulated() {
+ protected static boolean isExternalStorageEmulated() {
return sIsExternalStorageEmulated;
}
@@ -212,15 +211,12 @@ public class ShadowEnvironment {
storageState.put(directory.toPath(), state);
}
- /**
- * Shadow for {@link android.os.Environment.UserEnvironment}
- */
@Implements(className = "android.os.Environment$UserEnvironment", isInAndroidSdk = false,
minSdk = JELLY_BEAN_MR1)
public static class ShadowUserEnvironment {
@Implementation(minSdk = M)
- public File[] getExternalDirs() {
+ protected File[] getExternalDirs() {
return externalDirs.toArray(new File[externalDirs.size()]);
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowEuiccManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowEuiccManager.java
index db8d3d661..47e787db2 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowEuiccManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowEuiccManager.java
@@ -6,7 +6,6 @@ import android.telephony.euicc.EuiccManager;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
-/** Shadow for {@link EuiccManager}. */
@Implements(value = EuiccManager.class, minSdk = P)
public class ShadowEuiccManager {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowFilter.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowFilter.java
index daf08fa82..67fcbd7e4 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowFilter.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowFilter.java
@@ -12,7 +12,7 @@ public class ShadowFilter {
@RealObject private Filter realObject;
@Implementation
- public void filter(CharSequence constraint, Filter.FilterListener listener) {
+ protected void filter(CharSequence constraint, Filter.FilterListener listener) {
try {
Class<?> forName = Class.forName("android.widget.Filter$FilterResults");
Object filtering;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowFloatMath.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowFloatMath.java
index bcec84242..1f3fa9b1f 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowFloatMath.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowFloatMath.java
@@ -24,27 +24,27 @@ import org.robolectric.annotation.Implements;
@Implements(FloatMath.class)
public class ShadowFloatMath {
@Implementation
- public static float floor(float value) {
+ protected static float floor(float value) {
return (float) Math.floor(value);
}
@Implementation
- public static float ceil(float value) {
+ protected static float ceil(float value) {
return (float) Math.ceil(value);
}
@Implementation
- public static float sin(float angle) {
+ protected static float sin(float angle) {
return (float) Math.sin(angle);
}
@Implementation
- public static float cos(float angle) {
+ protected static float cos(float angle) {
return (float) Math.cos(angle);
}
@Implementation
- public static float sqrt(float value) {
+ protected static float sqrt(float value) {
return (float) Math.sqrt(value);
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowFontFamily.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowFontFamily.java
new file mode 100644
index 000000000..297417827
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowFontFamily.java
@@ -0,0 +1,20 @@
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.LOLLIPOP;
+import static android.os.Build.VERSION_CODES.O;
+
+import android.graphics.FontFamily;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(value = FontFamily.class, minSdk = LOLLIPOP, isInAndroidSdk = false)
+public class ShadowFontFamily {
+
+ @Implementation(minSdk = O)
+ protected static long nInitBuilder(String lang, int variant) {
+ return 1;
+ }
+
+ @Implementation(minSdk = O)
+ protected void abortCreation() {}
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowGLES20.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowGLES20.java
index 4c5901f7f..b49291567 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowGLES20.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowGLES20.java
@@ -1,4 +1,4 @@
-package com.google.android.libraries.youtube.edit.shadows;
+package org.robolectric.shadows;
import android.opengl.GLES20;
import org.robolectric.annotation.Implementation;
@@ -9,11 +9,19 @@ import org.robolectric.annotation.Implements;
*/
@Implements(GLES20.class)
public class ShadowGLES20 {
+ private static int framebufferCount = 0;
private static int textureCount = 0;
private static int shaderCount = 0;
private static int programCount = 0;
@Implementation
+ protected static void glGenFramebuffers(int n, int[] framebuffers, int offset) {
+ for (int i = 0; i < n; i++) {
+ framebuffers[offset + i] = ++framebufferCount;
+ }
+ }
+
+ @Implementation
protected static void glGenTextures(int n, int[] textures, int offset) {
for (int i = 0; i < n; i++) {
textures[offset + i] = ++textureCount;
@@ -32,4 +40,24 @@ public class ShadowGLES20 {
protected static int glCreateProgram() {
return ++programCount;
}
+
+ @Implementation
+ protected static void glGetShaderiv(int shader, int pname, int[] params, int offset) {
+ switch (pname) {
+ case GLES20.GL_COMPILE_STATUS:
+ params[0] = GLES20.GL_TRUE;
+ break;
+ default: // no-op
+ }
+ }
+
+ @Implementation
+ protected static void glGetProgramiv(int program, int pname, int[] params, int offset) {
+ switch (pname) {
+ case GLES20.GL_LINK_STATUS:
+ params[0] = GLES20.GL_TRUE;
+ break;
+ default: // no-op
+ }
+ }
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowGeocoder.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowGeocoder.java
index 9c61dd2e5..cb39f7f7e 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowGeocoder.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowGeocoder.java
@@ -16,11 +16,9 @@ public final class ShadowGeocoder {
private static boolean isPresent = true;
private List<Address> fromLocation = new ArrayList<>();
- /**
- * @return `true` by default, or the value specified via {@link #setIsPresent(boolean)}
- */
+ /** @return `true` by default, or the value specified via {@link #setIsPresent(boolean)} */
@Implementation
- public static boolean isPresent() {
+ protected static boolean isPresent() {
return isPresent;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowGradientDrawable.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowGradientDrawable.java
index 11be668b6..f6a0100eb 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowGradientDrawable.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowGradientDrawable.java
@@ -16,12 +16,18 @@ public class ShadowGradientDrawable extends ShadowDrawable {
private int color;
@Implementation
- public void setColor(int color) {
+ protected void setColor(int color) {
this.color = color;
directlyOn(realGradientDrawable, GradientDrawable.class).setColor(color);
}
- public int getColor() {
+ /**
+ * Returns the color of this drawable as set by the last call to {@link #setColor(int color)}.
+ *
+ * <p>Note that this only works if the color is explicitly set with {@link #setColor(int color)}.
+ * If the color of this drawable is set by another method, the result will be {@code 0}.
+ */
+ public int getLastSetColor() {
return color;
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHardwareRenderer.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHardwareRenderer.java
new file mode 100644
index 000000000..458f0fb82
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHardwareRenderer.java
@@ -0,0 +1,20 @@
+// BEGIN-INTERNAL
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.Q;
+
+import android.graphics.HardwareRenderer;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(value = HardwareRenderer.class, isInAndroidSdk = false, minSdk = Q)
+public class ShadowHardwareRenderer {
+
+ private static long nextCreateProxy = 0;
+
+ @Implementation
+ protected static long nCreateProxy(boolean translucent, long rootRenderNode) {
+ return ++nextCreateProxy;
+ }
+}
+// END-INTERNAL \ No newline at end of file
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHttpResponseCache.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHttpResponseCache.java
index 7697b704a..0fb712d4b 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHttpResponseCache.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHttpResponseCache.java
@@ -4,6 +4,7 @@ import static org.robolectric.shadow.api.Shadow.newInstanceOf;
import android.net.http.HttpResponseCache;
import java.io.File;
+import java.net.CacheRequest;
import java.net.CacheResponse;
import java.net.URI;
import java.net.URLConnection;
@@ -28,7 +29,7 @@ public class ShadowHttpResponseCache {
private int networkCount = 0;
@Implementation
- public static HttpResponseCache install(File directory, long maxSize) {
+ protected static HttpResponseCache install(File directory, long maxSize) {
HttpResponseCache cache = newInstanceOf(HttpResponseCache.class);
ShadowHttpResponseCache shadowCache = Shadow.extract(cache);
shadowCache.originalObject = cache;
@@ -41,58 +42,59 @@ public class ShadowHttpResponseCache {
}
@Implementation
- public static HttpResponseCache getInstalled() {
+ protected static HttpResponseCache getInstalled() {
synchronized (LOCK) {
return (installed != null) ? installed.originalObject : null;
}
}
@Implementation
- public long maxSize() {
+ protected long maxSize() {
return maxSize;
}
@Implementation
- public long size() {
+ protected long size() {
return 0;
}
@Implementation
- public void close() {
+ protected void close() {
synchronized (LOCK) {
installed = null;
}
}
@Implementation
- public void delete() {
+ protected void delete() {
close();
}
@Implementation
- public int getHitCount() {
+ protected int getHitCount() {
return hitCount;
}
@Implementation
- public int getNetworkCount() {
+ protected int getNetworkCount() {
return networkCount;
}
@Implementation
- public int getRequestCount() {
+ protected int getRequestCount() {
return requestCount;
}
@Implementation
- public CacheResponse get(URI uri, String requestMethod, Map<String, List<String>> requestHeaders) {
+ protected CacheResponse get(
+ URI uri, String requestMethod, Map<String, List<String>> requestHeaders) {
requestCount += 1;
networkCount += 1; // Always pretend we had a cache miss and had to fall back to the network.
return null;
}
@Implementation
- public CacheResponse put(URI uri, URLConnection urlConnection) {
+ protected CacheRequest put(URI uri, URLConnection urlConnection) {
// Do not cache any data. All requests will be a miss.
return null;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowImageDecoder.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowImageDecoder.java
index c321d4104..f7edf2406 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowImageDecoder.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowImageDecoder.java
@@ -26,7 +26,7 @@ import org.robolectric.shadow.api.Shadow;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.ReflectionHelpers.ClassParameter;
-// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r8/core/jni/android/graphics/ImageDecoder.cpp
+// transliterated from https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/core/jni/android/graphics/ImageDecoder.cpp
@SuppressWarnings({"NewApi", "UnusedDeclaration"})
// ImageDecoder is in fact in SDK, but make it false for now so projects which compile against < P
// still work
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputDevice.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputDevice.java
index caa021a76..c9552c0d6 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputDevice.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputDevice.java
@@ -17,7 +17,7 @@ public class ShadowInputDevice {
}
@Implementation
- public String getName() {
+ protected String getName() {
return deviceName;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputEvent.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputEvent.java
index 457be7053..86aa12b7b 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputEvent.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputEvent.java
@@ -10,7 +10,7 @@ public class ShadowInputEvent {
protected InputDevice device;
@Implementation
- public InputDevice getDevice() {
+ protected InputDevice getDevice() {
return device;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputEventReceiver.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputEventReceiver.java
index 227aa481b..1a15841d2 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputEventReceiver.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputEventReceiver.java
@@ -7,6 +7,7 @@ import org.robolectric.annotation.Implements;
@Implements(value = InputEventReceiver.class, isInAndroidSdk = false)
public class ShadowInputEventReceiver {
@Implementation
+ @SuppressWarnings("robolectric.ShadowReturnTypeMismatch")
public void consumeBatchedInputEvents(long frameTimeNanos) {
// The real implementation of this calls a JNI method, and logs a statement if the native
// object isn't present. Since the native object will never be present in Robolectric tests, it
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputManager.java
index a4e100460..4c8ebf509 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInputManager.java
@@ -9,9 +9,6 @@ import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;
import org.robolectric.util.ReflectionHelpers;
-/*
- * Shadow for InputManager.
- */
@Implements(value = InputManager.class)
public class ShadowInputManager {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInstrumentation.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInstrumentation.java
index d6acd01c4..d117de48c 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInstrumentation.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInstrumentation.java
@@ -79,12 +79,12 @@ public class ShadowInstrumentation {
private boolean checkActivities;
@Implementation(minSdk = P)
- public Activity startActivitySync(Intent intent, Bundle options) {
+ protected Activity startActivitySync(Intent intent, Bundle options) {
throw new UnsupportedOperationException("Implement me!!");
}
@Implementation
- public ActivityResult execStartActivity(
+ protected ActivityResult execStartActivity(
Context who,
IBinder contextThread,
IBinder token,
@@ -97,7 +97,7 @@ public class ShadowInstrumentation {
}
@Implementation(maxSdk = LOLLIPOP_MR1)
- public ActivityResult execStartActivity(
+ protected ActivityResult execStartActivity(
Context who,
IBinder contextThread,
IBinder token,
@@ -124,7 +124,7 @@ public class ShadowInstrumentation {
}
@Implementation
- public void execStartActivities(
+ protected void execStartActivities(
Context who,
IBinder contextThread,
IBinder token,
@@ -137,13 +137,13 @@ public class ShadowInstrumentation {
}
@Implementation(minSdk = LOLLIPOP)
- public void execStartActivityFromAppTask(
+ protected void execStartActivityFromAppTask(
Context who, IBinder contextThread, Object appTask, Intent intent, Bundle options) {
throw new UnsupportedOperationException("Implement me!!");
}
@Implementation(minSdk = M)
- public ActivityResult execStartActivity(
+ protected ActivityResult execStartActivity(
Context who,
IBinder contextThread,
IBinder token,
@@ -156,7 +156,7 @@ public class ShadowInstrumentation {
}
@Implementation(minSdk = JELLY_BEAN_MR1)
- public ActivityResult execStartActivity(
+ protected ActivityResult execStartActivity(
Context who,
IBinder contextThread,
IBinder token,
@@ -169,7 +169,7 @@ public class ShadowInstrumentation {
}
@Implementation(minSdk = M)
- public ActivityResult execStartActivityAsCaller(
+ protected ActivityResult execStartActivityAsCaller(
Context who,
IBinder contextThread,
IBinder token,
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowIntentService.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowIntentService.java
index 34c885222..06669266e 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowIntentService.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowIntentService.java
@@ -20,7 +20,7 @@ public class ShadowIntentService extends ShadowService {
}
@Implementation
- public void setIntentRedelivery(boolean enabled) {
+ protected void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
directlyOn(realIntentService, IntentService.class, "setIntentRedelivery", ClassParameter.from(boolean.class, enabled));
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowIoUtils.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowIoUtils.java
index 77cde7ab6..62360eeb1 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowIoUtils.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowIoUtils.java
@@ -2,12 +2,12 @@ package org.robolectric.shadows;
import static java.nio.charset.StandardCharsets.UTF_8;
+import android.os.Build;
import java.io.FileDescriptor;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import libcore.io.IoUtils;
-import libcore.util.NonNull;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -19,9 +19,10 @@ public class ShadowIoUtils {
return new String(Files.readAllBytes(Paths.get(absolutePath)), UTF_8);
}
- //BEGIN-INTERNAL
- @Implementation(minSdk = android.os.Build.VERSION_CODES.Q)
- public static void setFdOwner(@NonNull FileDescriptor fd, @NonNull Object owner) {
+ // BEGIN-INTERNAL
+ @Implementation(minSdk = Build.VERSION_CODES.Q)
+ protected static void setFdOwner(FileDescriptor fd, Object owner) {
+ // ignore, fails in JVM environment
}
- //END-INTERNAL
+ // END-INTERNAL
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowJobScheduler.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowJobScheduler.java
index ab0908961..5725b7f65 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowJobScheduler.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowJobScheduler.java
@@ -14,6 +14,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -21,22 +22,23 @@ import org.robolectric.annotation.Implements;
public abstract class ShadowJobScheduler {
@Implementation
- public abstract int schedule(JobInfo job);
+ protected abstract int schedule(JobInfo job);
@Implementation
- public abstract void cancel(int jobId);
+ protected abstract void cancel(int jobId);
@Implementation
- public abstract void cancelAll();
+ protected abstract void cancelAll();
@Implementation
- public abstract List<JobInfo> getAllPendingJobs();
+ protected abstract List<JobInfo> getAllPendingJobs();
@Implementation(minSdk = N)
+ @HiddenApi
public abstract JobInfo getPendingJob(int jobId);
@Implementation(minSdk = O)
- public abstract int enqueue(JobInfo job, JobWorkItem work);
+ protected abstract int enqueue(JobInfo job, JobWorkItem work);
public abstract void failOnJob(int jobId);
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowJobService.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowJobService.java
index fee5f86ff..42baa4c1f 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowJobService.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowJobService.java
@@ -7,10 +7,6 @@ import android.app.job.JobService;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
-/**
- * Shadow for classes that extend jobservice. The shadowOf method can be used to obtain an instances
- * shadow to view state using utility methods.
- */
@Implements(value = JobService.class, minSdk = LOLLIPOP)
public class ShadowJobService extends ShadowService {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowJsResult.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowJsResult.java
index aa6429318..cf125510a 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowJsResult.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowJsResult.java
@@ -10,7 +10,7 @@ public class ShadowJsResult {
private boolean wasCancelled;
@Implementation
- public void cancel() {
+ protected void cancel() {
wasCancelled = true;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowKeyCharacterMap.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowKeyCharacterMap.java
index b8235c645..b10e462f8 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowKeyCharacterMap.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowKeyCharacterMap.java
@@ -92,12 +92,12 @@ public class ShadowKeyCharacterMap {
}
@Implementation
- public static KeyCharacterMap load(int deviceId) {
+ protected static KeyCharacterMap load(int deviceId) {
return ReflectionHelpers.callConstructor(KeyCharacterMap.class);
}
@Implementation
- public KeyEvent[] getEvents(char[] charArray) {
+ protected KeyEvent[] getEvents(char[] charArray) {
int eventsPerChar = 2;
KeyEvent[] events = new KeyEvent[charArray.length * eventsPerChar];
@@ -110,12 +110,12 @@ public class ShadowKeyCharacterMap {
}
@Implementation
- public int getKeyboardType() {
+ protected int getKeyboardType() {
return KeyCharacterMap.FULL;
}
@Implementation
- public int get(int keyCode, int metaState) {
+ protected int get(int keyCode, int metaState) {
return Character.toLowerCase(KEY_CODE_TO_CHAR.get(keyCode));
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLegacyApkAssets.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLegacyApkAssets.java
index 57b3f978b..d709e452d 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLegacyApkAssets.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLegacyApkAssets.java
@@ -7,7 +7,7 @@ import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
// transliterated from
-// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r3/core/jni/android_content_res_ApkAssets.cpp
+// https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r12/core/jni/android_content_res_ApkAssets.cpp
@Implements(value = android.content.res.ApkAssets.class, minSdk = Build.VERSION_CODES.P, isInAndroidSdk = false)
public class ShadowLegacyApkAssets extends ShadowApkAssets {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLegacyAssetManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLegacyAssetManager.java
index 35a9b675e..a914dc830 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLegacyAssetManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLegacyAssetManager.java
@@ -82,7 +82,6 @@ import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowAssetManager.Picker;
import org.robolectric.util.Logger;
import org.robolectric.util.ReflectionHelpers;
-import org.robolectric.util.ReflectionHelpers.ClassParameter;
@SuppressLint("NewApi")
@Implements(value = AssetManager.class, /* this one works for P too... maxSdk = VERSION_CODES.O_MR1,*/
@@ -237,22 +236,22 @@ public class ShadowLegacyAssetManager extends ShadowAssetManager {
protected void __constructor__() {
resourceTable = RuntimeEnvironment.getAppResourceTable();
-
+
if (RuntimeEnvironment.getApiLevel() >= P) {
invokeConstructor(AssetManager.class, realObject);
}
-
+
}
@Implementation
protected void __constructor__(boolean isSystem) {
resourceTable = isSystem ? RuntimeEnvironment.getSystemResourceTable() : RuntimeEnvironment.getAppResourceTable();
-
+
if (RuntimeEnvironment.getApiLevel() >= P) {
invokeConstructor(AssetManager.class, realObject, from(boolean.class, isSystem));
}
-
+
}
@Implementation(minSdk = P)
@@ -372,17 +371,17 @@ public class ShadowLegacyAssetManager extends ShadowAssetManager {
}
@Implementation
- public final InputStream open(String fileName) throws IOException {
+ protected final InputStream open(String fileName) throws IOException {
return findAssetFile(fileName).getInputStream();
}
@Implementation
- public final InputStream open(String fileName, int accessMode) throws IOException {
+ protected final InputStream open(String fileName, int accessMode) throws IOException {
return findAssetFile(fileName).getInputStream();
}
@Implementation
- public final AssetFileDescriptor openFd(String fileName) throws IOException {
+ protected final AssetFileDescriptor openFd(String fileName) throws IOException {
File file = new File(findAssetFile(fileName).getPath());
if (file.getPath().startsWith("jar")) {
file = getFileFromZip(file);
@@ -442,7 +441,7 @@ public class ShadowLegacyAssetManager extends ShadowAssetManager {
}
@Implementation
- public final String[] list(String path) throws IOException {
+ protected final String[] list(String path) throws IOException {
List<String> assetFiles = new ArrayList<>();
for (FsFile assetsDir : getAllAssetDirs()) {
@@ -532,7 +531,8 @@ public class ShadowLegacyAssetManager extends ShadowAssetManager {
}
@Implementation
- public final XmlResourceParser openXmlResourceParser(int cookie, String fileName) throws IOException {
+ protected final XmlResourceParser openXmlResourceParser(int cookie, String fileName)
+ throws IOException {
XmlBlock xmlBlock = XmlBlock.create(Fs.fileFromPath(fileName), resourceTable.getPackageName());
if (xmlBlock == null) {
throw new Resources.NotFoundException(fileName);
@@ -653,7 +653,7 @@ public class ShadowLegacyAssetManager extends ShadowAssetManager {
}
@Implementation
- public String[] getLocales() {
+ protected String[] getLocales() {
return new String[0]; // todo
}
@@ -862,7 +862,7 @@ public class ShadowLegacyAssetManager extends ShadowAssetManager {
}
}
- @HiddenApi @Implementation(minSdk = LOLLIPOP)
+ @HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1)
protected static void dumpTheme(long theme, int priority, String tag, String prefix) {
throw new UnsupportedOperationException("not yet implemented");
}
@@ -932,15 +932,15 @@ public class ShadowLegacyAssetManager extends ShadowAssetManager {
// BEGIN-INTERNAL
@HiddenApi @Implementation(minSdk = Q)
protected static void nativeThemeCopy(long dstAssetManagerPtr, long dstThemePtr,
- long srcAssetManagerPtr, long srcThemePtr) {
+ long srcAssetManagerPtr, long srcThemePtr) {
copyTheme(dstThemePtr, srcThemePtr);
}
// END-INTERNAL
@HiddenApi @Implementation(maxSdk = KITKAT_WATCH)
- protected static void applyStyle(int themeToken, int defStyleAttr, int defStyleRes,
+ protected static boolean applyStyle(int themeToken, int defStyleAttr, int defStyleRes,
int xmlParserToken, int[] attrs, int[] outValues, int[] outIndices) {
- applyStyle((long)themeToken, defStyleAttr, defStyleRes, (long)xmlParserToken, attrs,
+ return applyStyle((long)themeToken, defStyleAttr, defStyleRes, (long)xmlParserToken, attrs,
outValues, outIndices);
}
@@ -961,12 +961,13 @@ public class ShadowLegacyAssetManager extends ShadowAssetManager {
}
@HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = N_MR1)
- protected static void applyStyle(long themeToken, int defStyleAttr, int defStyleRes,
+ protected static boolean applyStyle(long themeToken, int defStyleAttr, int defStyleRes,
long xmlParserToken, int[] attrs, int[] outValues, int[] outIndices) {
// no-op
+ return false;
}
- @HiddenApi @Implementation(minSdk = LOLLIPOP)
+ @HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1)
protected static boolean resolveAttrs(long themeToken,
int defStyleAttr, int defStyleRes, int[] inValues,
int[] attrs, int[] outValues, int[] outIndices) {
@@ -1288,22 +1289,22 @@ public class ShadowLegacyAssetManager extends ShadowAssetManager {
}
@Implementation
- public String getResourceName(int resid) {
+ protected String getResourceName(int resid) {
return getResName(resid).getFullyQualifiedName();
}
@Implementation
- public String getResourcePackageName(int resid) {
+ protected String getResourcePackageName(int resid) {
return getResName(resid).packageName;
}
@Implementation
- public String getResourceTypeName(int resid) {
+ protected String getResourceTypeName(int resid) {
return getResName(resid).type;
}
@Implementation
- public String getResourceEntryName(int resid) {
+ protected String getResourceEntryName(int resid) {
return getResName(resid).name;
}
@@ -1323,7 +1324,7 @@ public class ShadowLegacyAssetManager extends ShadowAssetManager {
}
@Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1)
- public final SparseArray<String> getAssignedPackageIdentifiers() {
+ protected final SparseArray<String> getAssignedPackageIdentifiers() {
return new SparseArray<>();
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinearGradient.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinearGradient.java
index a7597d2ee..27fab96c2 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinearGradient.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinearGradient.java
@@ -17,7 +17,7 @@ public class ShadowLinearGradient {
private Shader.TileMode tile;
@Implementation
- public void __constructor__(
+ protected void __constructor__(
float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile) {
this.x0 = x0;
this.y0 = y0;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinkMovementMethod.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinkMovementMethod.java
index 0286c0919..4df7e345c 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinkMovementMethod.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinkMovementMethod.java
@@ -9,7 +9,7 @@ import org.robolectric.annotation.Implements;
@Implements(LinkMovementMethod.class)
public class ShadowLinkMovementMethod {
@Implementation
- public static MovementMethod getInstance() {
+ protected static MovementMethod getInstance() {
return new LinkMovementMethod();
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinux.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinux.java
index b7d8b3b90..0e480ceec 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinux.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLinux.java
@@ -18,7 +18,7 @@ import org.robolectric.annotation.Implements;
@Implements(value = Linux.class, minSdk = Build.VERSION_CODES.O, isInAndroidSdk = false)
public class ShadowLinux {
@Implementation
- public static void mkdir(String path, int mode) throws ErrnoException {
+ public void mkdir(String path, int mode) throws ErrnoException {
new File(path).mkdirs();
}
@@ -51,7 +51,7 @@ public class ShadowLinux {
}
@Implementation
- protected static FileDescriptor open(String path, int flags, int mode) throws ErrnoException {
+ protected FileDescriptor open(String path, int flags, int mode) throws ErrnoException {
try {
RandomAccessFile randomAccessFile = new RandomAccessFile(path, modeToString(mode));
return randomAccessFile.getFD();
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowListPopupWindow.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowListPopupWindow.java
index 3d4ad7979..ce198a5ad 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowListPopupWindow.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowListPopupWindow.java
@@ -11,12 +11,12 @@ import org.robolectric.shadow.api.Shadow;
@Implements(ListPopupWindow.class)
public class ShadowListPopupWindow {
-
+
@RealObject
private ListPopupWindow realListPopupWindow;
@Implementation
- public void show() {
+ protected void show() {
ShadowApplication shadowApplication = Shadow.extract(RuntimeEnvironment.application);
shadowApplication.setLatestListPopupWindow(realListPopupWindow);
directlyOn(realListPopupWindow, ListPopupWindow.class).show();
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLocationManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLocationManager.java
index fc62e4069..027695fe5 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLocationManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLocationManager.java
@@ -55,7 +55,7 @@ public class ShadowLocationManager {
long lastSeenTime;
ListenerRegistration(String provider, long minTime, float minDistance, Location locationAtCreation,
- LocationListener listener) {
+ LocationListener listener) {
this.provider = provider;
this.minTime = minTime;
this.minDistance = minDistance;
@@ -70,7 +70,7 @@ public class ShadowLocationManager {
new HashMap<>();
@Implementation
- public boolean isProviderEnabled(String provider) {
+ protected boolean isProviderEnabled(String provider) {
LocationProviderEntry map = providersEnabled.get(provider);
if (map != null) {
Boolean isEnabled = map.getKey();
@@ -80,7 +80,7 @@ public class ShadowLocationManager {
}
@Implementation
- public List<String> getAllProviders() {
+ protected List<String> getAllProviders() {
Set<String> allKnownProviders = new LinkedHashSet<>(providersEnabled.keySet());
allKnownProviders.add(LocationManager.GPS_PROVIDER);
allKnownProviders.add(LocationManager.NETWORK_PROVIDER);
@@ -138,7 +138,7 @@ public class ShadowLocationManager {
}
@Implementation
- public List<String> getProviders(boolean enabledOnly) {
+ protected List<String> getProviders(boolean enabledOnly) {
ArrayList<String> enabledProviders = new ArrayList<>();
for (String provider : getAllProviders()) {
if (!enabledOnly || providersEnabled.get(provider) != null) {
@@ -149,12 +149,12 @@ public class ShadowLocationManager {
}
@Implementation
- public Location getLastKnownLocation(String provider) {
+ protected Location getLastKnownLocation(String provider) {
return lastKnownLocations.get(provider);
}
@Implementation
- public boolean addGpsStatusListener(Listener listener) {
+ protected boolean addGpsStatusListener(Listener listener) {
if (!gpsStatusListeners.contains(listener)) {
gpsStatusListeners.add(listener);
}
@@ -162,12 +162,12 @@ public class ShadowLocationManager {
}
@Implementation
- public void removeGpsStatusListener(Listener listener) {
+ protected void removeGpsStatusListener(Listener listener) {
gpsStatusListeners.remove(listener);
}
@Implementation
- public String getBestProvider(Criteria criteria, boolean enabled) {
+ protected String getBestProvider(Criteria criteria, boolean enabled) {
lastBestProviderCriteria = criteria;
lastBestProviderEnabled = enabled;
@@ -231,20 +231,21 @@ public class ShadowLocationManager {
// @SystemApi
@Implementation(minSdk = P)
- public void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
+ protected void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
getContext().checkCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS);
locationEnabledForUser.put(userHandle, enabled);
}
// @SystemApi
@Implementation(minSdk = P)
- public boolean isLocationEnabledForUser(UserHandle userHandle) {
+ protected boolean isLocationEnabledForUser(UserHandle userHandle) {
Boolean result = locationEnabledForUser.get(userHandle);
return result == null ? false : result;
}
@Implementation
- public void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener) {
+ protected void requestLocationUpdates(
+ String provider, long minTime, float minDistance, LocationListener listener) {
addLocationListener(provider, listener, minTime, minDistance);
}
@@ -271,13 +272,14 @@ public class ShadowLocationManager {
}
@Implementation
- public void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener,
- Looper looper) {
+ protected void requestLocationUpdates(
+ String provider, long minTime, float minDistance, LocationListener listener, Looper looper) {
addLocationListener(provider, listener, minTime, minDistance);
}
@Implementation
- public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria, PendingIntent pendingIntent) {
+ protected void requestLocationUpdates(
+ long minTime, float minDistance, Criteria criteria, PendingIntent pendingIntent) {
if (pendingIntent == null) {
throw new IllegalStateException("Intent must not be null");
}
@@ -288,8 +290,8 @@ public class ShadowLocationManager {
}
@Implementation
- public void requestLocationUpdates(String provider, long minTime, float minDistance,
- PendingIntent pendingIntent) {
+ protected void requestLocationUpdates(
+ String provider, long minTime, float minDistance, PendingIntent pendingIntent) {
if (pendingIntent == null) {
throw new IllegalStateException("Intent must not be null");
}
@@ -301,7 +303,7 @@ public class ShadowLocationManager {
}
@Implementation
- public void removeUpdates(LocationListener listener) {
+ protected void removeUpdates(LocationListener listener) {
removedLocationListeners.add(listener);
}
@@ -318,7 +320,7 @@ public class ShadowLocationManager {
}
@Implementation
- public void removeUpdates(PendingIntent pendingIntent) {
+ protected void removeUpdates(PendingIntent pendingIntent) {
while (requestLocationUdpateCriteriaPendingIntents.remove(pendingIntent) != null);
while (requestLocationUdpateProviderPendingIntents.remove(pendingIntent) != null);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLog.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLog.java
index be30606c2..9f49e49c5 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLog.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLog.java
@@ -33,72 +33,72 @@ public class ShadowLog {
private static boolean wtfIsFatal = false;
@Implementation
- public static void e(String tag, String msg) {
- e(tag, msg, null);
+ protected static int e(String tag, String msg) {
+ return e(tag, msg, null);
}
@Implementation
- public static void e(String tag, String msg, Throwable throwable) {
- addLog(Log.ERROR, tag, msg, throwable);
+ protected static int e(String tag, String msg, Throwable throwable) {
+ return addLog(Log.ERROR, tag, msg, throwable);
}
@Implementation
- public static void d(String tag, String msg) {
- d(tag, msg, null);
+ protected static int d(String tag, String msg) {
+ return d(tag, msg, null);
}
@Implementation
- public static void d(String tag, String msg, Throwable throwable) {
- addLog(Log.DEBUG, tag, msg, throwable);
+ protected static int d(String tag, String msg, Throwable throwable) {
+ return addLog(Log.DEBUG, tag, msg, throwable);
}
@Implementation
- public static void i(String tag, String msg) {
- i(tag, msg, null);
+ protected static int i(String tag, String msg) {
+ return i(tag, msg, null);
}
@Implementation
- public static void i(String tag, String msg, Throwable throwable) {
- addLog(Log.INFO, tag, msg, throwable);
+ protected static int i(String tag, String msg, Throwable throwable) {
+ return addLog(Log.INFO, tag, msg, throwable);
}
@Implementation
- public static void v(String tag, String msg) {
- v(tag, msg, null);
+ protected static int v(String tag, String msg) {
+ return v(tag, msg, null);
}
@Implementation
- public static void v(String tag, String msg, Throwable throwable) {
- addLog(Log.VERBOSE, tag, msg, throwable);
+ protected static int v(String tag, String msg, Throwable throwable) {
+ return addLog(Log.VERBOSE, tag, msg, throwable);
}
@Implementation
- public static void w(String tag, String msg) {
- w(tag, msg, null);
+ protected static int w(String tag, String msg) {
+ return w(tag, msg, null);
}
@Implementation
- public static void w(String tag, Throwable throwable) {
- w(tag, null, throwable);
+ protected static int w(String tag, Throwable throwable) {
+ return w(tag, null, throwable);
}
-
@Implementation
- public static void w(String tag, String msg, Throwable throwable) {
- addLog(Log.WARN, tag, msg, throwable);
+ protected static int w(String tag, String msg, Throwable throwable) {
+ return addLog(Log.WARN, tag, msg, throwable);
}
@Implementation
- public static void wtf(String tag, String msg) {
- wtf(tag, msg, null);
+ protected static int wtf(String tag, String msg) {
+ return wtf(tag, msg, null);
}
@Implementation
- public static void wtf(String tag, String msg, Throwable throwable) {
+ protected static int wtf(String tag, String msg, Throwable throwable) {
addLog(Log.ASSERT, tag, msg, throwable);
if (wtfIsFatal) {
throw new TerribleFailure(msg, throwable);
}
+ return 0;
}
/** Sets whether calling {@link Log#wtf} will throw {@link TerribleFailure}. */
@@ -107,7 +107,7 @@ public class ShadowLog {
}
@Implementation
- public static boolean isLoggable(String tag, int level) {
+ protected static boolean isLoggable(String tag, int level) {
synchronized (tagToLevel) {
if (tagToLevel.containsKey(tag)) {
return level >= tagToLevel.get(tag);
@@ -133,7 +133,7 @@ public class ShadowLog {
tagToLevel.put(tag, level);
}
- private static void addLog(int level, String tag, String msg, Throwable throwable) {
+ private static int addLog(int level, String tag, String msg, Throwable throwable) {
if (stream != null) {
logToStream(stream, level, tag, msg, throwable);
}
@@ -152,6 +152,8 @@ public class ShadowLog {
itemList.add(item);
logs.add(item);
+
+ return 0;
}
private static void logToStream(PrintStream ps, int level, String tag, String msg, Throwable throwable) {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLooper.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLooper.java
index b8724ff5d..5e91f50a6 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLooper.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLooper.java
@@ -30,6 +30,7 @@ import org.robolectric.util.Scheduler;
@Implements(Looper.class)
@SuppressWarnings("SynchronizeOnNonFinalField")
public class ShadowLooper {
+
// Replaced SoftThreadLocal with a WeakHashMap, because ThreadLocal make it impossible to access their contents from other
// threads, but we need to be able to access the loopers for all threads so that we can shut them down when resetThreadLoopers()
// is called. This also allows us to implement the useful getLooperForThread() method.
@@ -73,7 +74,7 @@ public class ShadowLooper {
}
@Implementation
- public void __constructor__(boolean quitAllowed) {
+ protected void __constructor__(boolean quitAllowed) {
invokeConstructor(Looper.class, realObject, from(boolean.class, quitAllowed));
if (isMainThread()) {
mainLooper = realObject;
@@ -84,17 +85,17 @@ public class ShadowLooper {
}
@Implementation
- public static Looper getMainLooper() {
+ protected static Looper getMainLooper() {
return mainLooper;
}
@Implementation
- public static Looper myLooper() {
+ protected static Looper myLooper() {
return getLooperForThread(Thread.currentThread());
}
@Implementation
- public static void loop() {
+ protected static void loop() {
shadowOf(Looper.myLooper()).doLoop();
}
@@ -112,13 +113,13 @@ public class ShadowLooper {
}
@Implementation
- public void quit() {
+ protected void quit() {
if (realObject == Looper.getMainLooper()) throw new RuntimeException("Main thread not allowed to quit");
quitUnchecked();
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public void quitSafely() {
+ protected void quitSafely() {
quit();
}
@@ -137,6 +138,8 @@ public class ShadowLooper {
}
}
+ /** @deprecated Use `shadowOf({@link Looper#getMainLooper()})` instead. */
+ @Deprecated
public static ShadowLooper getShadowMainLooper() {
return shadowOf(Looper.getMainLooper());
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMatrix.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMatrix.java
index 80267f471..2b1b5b1d6 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMatrix.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMatrix.java
@@ -4,8 +4,10 @@ import static android.os.Build.VERSION_CODES.KITKAT;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import android.graphics.Matrix;
+import android.graphics.Matrix.ScaleToFit;
import android.graphics.PointF;
import android.graphics.RectF;
+import java.awt.geom.AffineTransform;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
@@ -35,10 +37,10 @@ public class ShadowMatrix {
private final Deque<String> postOps = new ArrayDeque<>();
private final Map<String, String> setOps = new LinkedHashMap<>();
- private SimpleMatrix mMatrix = SimpleMatrix.IDENTITY;
+ private SimpleMatrix simpleMatrix = SimpleMatrix.newIdentityMatrix();
@Implementation
- public void __constructor__(Matrix src) {
+ protected void __constructor__(Matrix src) {
set(src);
}
@@ -69,229 +71,247 @@ public class ShadowMatrix {
}
@Implementation
- public boolean isIdentity() {
- return mMatrix.equals(SimpleMatrix.IDENTITY);
+ protected boolean isIdentity() {
+ return simpleMatrix.equals(SimpleMatrix.IDENTITY);
}
@Implementation(minSdk = LOLLIPOP)
- public boolean isAffine() {
- return mMatrix.isAffine();
+ protected boolean isAffine() {
+ return simpleMatrix.isAffine();
}
@Implementation
- public boolean rectStaysRect() {
- return mMatrix.rectStaysRect();
+ protected boolean rectStaysRect() {
+ return simpleMatrix.rectStaysRect();
}
@Implementation
- public void getValues(float[] values) {
- mMatrix.getValues(values);
+ protected void getValues(float[] values) {
+ simpleMatrix.getValues(values);
}
@Implementation
- public void setValues(float[] values) {
- mMatrix = new SimpleMatrix(values);
+ protected void setValues(float[] values) {
+ simpleMatrix = new SimpleMatrix(values);
}
@Implementation
- public void set(Matrix src) {
+ protected void set(Matrix src) {
reset();
if (src != null) {
ShadowMatrix shadowMatrix = Shadow.extract(src);
preOps.addAll(shadowMatrix.preOps);
postOps.addAll(shadowMatrix.postOps);
setOps.putAll(shadowMatrix.setOps);
- mMatrix = new SimpleMatrix(getSimpleMatrix(src));
+ simpleMatrix = new SimpleMatrix(getSimpleMatrix(src));
}
}
@Implementation
- public void reset() {
+ protected void reset() {
preOps.clear();
postOps.clear();
setOps.clear();
- mMatrix = SimpleMatrix.IDENTITY;
+ simpleMatrix = SimpleMatrix.newIdentityMatrix();
}
@Implementation
- public void setTranslate(float dx, float dy) {
+ protected void setTranslate(float dx, float dy) {
setOps.put(TRANSLATE, dx + " " + dy);
- mMatrix = SimpleMatrix.translate(dx, dy);
+ simpleMatrix = SimpleMatrix.translate(dx, dy);
}
@Implementation
- public void setScale(float sx, float sy, float px, float py) {
+ protected void setScale(float sx, float sy, float px, float py) {
setOps.put(SCALE, sx + " " + sy + " " + px + " " + py);
- mMatrix = SimpleMatrix.scale(sx, sy, px, py);
+ simpleMatrix = SimpleMatrix.scale(sx, sy, px, py);
}
@Implementation
- public void setScale(float sx, float sy) {
+ protected void setScale(float sx, float sy) {
setOps.put(SCALE, sx + " " + sy);
- mMatrix = SimpleMatrix.scale(sx, sy);
+ simpleMatrix = SimpleMatrix.scale(sx, sy);
}
@Implementation
- public void setRotate(float degrees, float px, float py) {
+ protected void setRotate(float degrees, float px, float py) {
setOps.put(ROTATE, degrees + " " + px + " " + py);
- mMatrix = SimpleMatrix.rotate(degrees, px, py);
+ simpleMatrix = SimpleMatrix.rotate(degrees, px, py);
}
@Implementation
- public void setRotate(float degrees) {
+ protected void setRotate(float degrees) {
setOps.put(ROTATE, Float.toString(degrees));
- mMatrix = SimpleMatrix.rotate(degrees);
+ simpleMatrix = SimpleMatrix.rotate(degrees);
}
@Implementation
- public void setSinCos(float sinValue, float cosValue, float px, float py) {
+ protected void setSinCos(float sinValue, float cosValue, float px, float py) {
setOps.put(SINCOS, sinValue + " " + cosValue + " " + px + " " + py);
- mMatrix = SimpleMatrix.sinCos(sinValue, cosValue, px, py);
+ simpleMatrix = SimpleMatrix.sinCos(sinValue, cosValue, px, py);
}
@Implementation
- public void setSinCos(float sinValue, float cosValue) {
+ protected void setSinCos(float sinValue, float cosValue) {
setOps.put(SINCOS, sinValue + " " + cosValue);
- mMatrix = SimpleMatrix.sinCos(sinValue, cosValue);
+ simpleMatrix = SimpleMatrix.sinCos(sinValue, cosValue);
}
@Implementation
- public void setSkew(float kx, float ky, float px, float py) {
+ protected void setSkew(float kx, float ky, float px, float py) {
setOps.put(SKEW, kx + " " + ky + " " + px + " " + py);
- mMatrix = SimpleMatrix.skew(kx, ky, px, py);
+ simpleMatrix = SimpleMatrix.skew(kx, ky, px, py);
}
@Implementation
- public void setSkew(float kx, float ky) {
+ protected void setSkew(float kx, float ky) {
setOps.put(SKEW, kx + " " + ky);
- mMatrix = SimpleMatrix.skew(kx, ky);
+ simpleMatrix = SimpleMatrix.skew(kx, ky);
}
@Implementation
- public boolean setConcat(Matrix a, Matrix b) {
- mMatrix = getSimpleMatrix(a).multiply(getSimpleMatrix(b));
+ protected boolean setConcat(Matrix a, Matrix b) {
+ simpleMatrix = getSimpleMatrix(a).multiply(getSimpleMatrix(b));
return true;
}
@Implementation
- public boolean preTranslate(float dx, float dy) {
+ protected boolean preTranslate(float dx, float dy) {
preOps.addFirst(TRANSLATE + " " + dx + " " + dy);
return preConcat(SimpleMatrix.translate(dx, dy));
}
@Implementation
- public boolean preScale(float sx, float sy, float px, float py) {
+ protected boolean preScale(float sx, float sy, float px, float py) {
preOps.addFirst(SCALE + " " + sx + " " + sy + " " + px + " " + py);
return preConcat(SimpleMatrix.scale(sx, sy, px, py));
}
@Implementation
- public boolean preScale(float sx, float sy) {
+ protected boolean preScale(float sx, float sy) {
preOps.addFirst(SCALE + " " + sx + " " + sy);
return preConcat(SimpleMatrix.scale(sx, sy));
}
@Implementation
- public boolean preRotate(float degrees, float px, float py) {
+ protected boolean preRotate(float degrees, float px, float py) {
preOps.addFirst(ROTATE + " " + degrees + " " + px + " " + py);
return preConcat(SimpleMatrix.rotate(degrees, px, py));
}
@Implementation
- public boolean preRotate(float degrees) {
+ protected boolean preRotate(float degrees) {
preOps.addFirst(ROTATE + " " + Float.toString(degrees));
return preConcat(SimpleMatrix.rotate(degrees));
}
@Implementation
- public boolean preSkew(float kx, float ky, float px, float py) {
+ protected boolean preSkew(float kx, float ky, float px, float py) {
preOps.addFirst(SKEW + " " + kx + " " + ky + " " + px + " " + py);
return preConcat(SimpleMatrix.skew(kx, ky, px, py));
}
@Implementation
- public boolean preSkew(float kx, float ky) {
+ protected boolean preSkew(float kx, float ky) {
preOps.addFirst(SKEW + " " + kx + " " + ky);
return preConcat(SimpleMatrix.skew(kx, ky));
}
@Implementation
- public boolean preConcat(Matrix other) {
+ protected boolean preConcat(Matrix other) {
preOps.addFirst(MATRIX + " " + other);
return preConcat(getSimpleMatrix(other));
}
@Implementation
- public boolean postTranslate(float dx, float dy) {
+ protected boolean postTranslate(float dx, float dy) {
postOps.addLast(TRANSLATE + " " + dx + " " + dy);
return postConcat(SimpleMatrix.translate(dx, dy));
}
@Implementation
- public boolean postScale(float sx, float sy, float px, float py) {
+ protected boolean postScale(float sx, float sy, float px, float py) {
postOps.addLast(SCALE + " " + sx + " " + sy + " " + px + " " + py);
return postConcat(SimpleMatrix.scale(sx, sy, px, py));
}
@Implementation
- public boolean postScale(float sx, float sy) {
+ protected boolean postScale(float sx, float sy) {
postOps.addLast(SCALE + " " + sx + " " + sy);
return postConcat(SimpleMatrix.scale(sx, sy));
}
@Implementation
- public boolean postRotate(float degrees, float px, float py) {
+ protected boolean postRotate(float degrees, float px, float py) {
postOps.addLast(ROTATE + " " + degrees + " " + px + " " + py);
return postConcat(SimpleMatrix.rotate(degrees, px, py));
}
@Implementation
- public boolean postRotate(float degrees) {
+ protected boolean postRotate(float degrees) {
postOps.addLast(ROTATE + " " + Float.toString(degrees));
return postConcat(SimpleMatrix.rotate(degrees));
}
@Implementation
- public boolean postSkew(float kx, float ky, float px, float py) {
+ protected boolean postSkew(float kx, float ky, float px, float py) {
postOps.addLast(SKEW + " " + kx + " " + ky + " " + px + " " + py);
return postConcat(SimpleMatrix.skew(kx, ky, px, py));
}
@Implementation
- public boolean postSkew(float kx, float ky) {
+ protected boolean postSkew(float kx, float ky) {
postOps.addLast(SKEW + " " + kx + " " + ky);
return postConcat(SimpleMatrix.skew(kx, ky));
}
@Implementation
- public boolean postConcat(Matrix other) {
+ protected boolean postConcat(Matrix other) {
postOps.addLast(MATRIX + " " + other);
return postConcat(getSimpleMatrix(other));
}
@Implementation
- public boolean invert(Matrix inverse) {
- final SimpleMatrix inverseMatrix = mMatrix.invert();
+ protected boolean invert(Matrix inverse) {
+ final SimpleMatrix inverseMatrix = simpleMatrix.invert();
if (inverseMatrix != null) {
if (inverse != null) {
final ShadowMatrix shadowInverse = Shadow.extract(inverse);
- shadowInverse.mMatrix = inverseMatrix;
+ shadowInverse.simpleMatrix = inverseMatrix;
}
return true;
}
return false;
}
+ boolean hasPerspective() {
+ return (simpleMatrix.mValues[6] != 0 || simpleMatrix.mValues[7] != 0 || simpleMatrix.mValues[8] != 1);
+ }
+
+ protected AffineTransform getAffineTransform() {
+ // the AffineTransform constructor takes the value in a different order
+ // for a matrix [ 0 1 2 ]
+ // [ 3 4 5 ]
+ // the order is 0, 3, 1, 4, 2, 5...
+ return new AffineTransform(
+ simpleMatrix.mValues[0],
+ simpleMatrix.mValues[3],
+ simpleMatrix.mValues[1],
+ simpleMatrix.mValues[4],
+ simpleMatrix.mValues[2],
+ simpleMatrix.mValues[5]);
+ }
+
public PointF mapPoint(float x, float y) {
- return mMatrix.transform(new PointF(x, y));
+ return simpleMatrix.transform(new PointF(x, y));
}
public PointF mapPoint(PointF point) {
- return mMatrix.transform(point);
+ return simpleMatrix.transform(point);
}
@Implementation
- public boolean mapRect(RectF destination, RectF source) {
+ protected boolean mapRect(RectF destination, RectF source) {
final PointF leftTop = mapPoint(source.left, source.top);
final PointF rightBottom = mapPoint(source.right, source.bottom);
destination.set(
@@ -313,11 +333,11 @@ public class ShadowMatrix {
@Implementation
protected void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int vectorCount) {
- final float transX = mMatrix.mValues[Matrix.MTRANS_X];
- final float transY = mMatrix.mValues[Matrix.MTRANS_Y];
+ final float transX = simpleMatrix.mValues[Matrix.MTRANS_X];
+ final float transY = simpleMatrix.mValues[Matrix.MTRANS_Y];
- mMatrix.mValues[Matrix.MTRANS_X] = 0;
- mMatrix.mValues[Matrix.MTRANS_Y] = 0;
+ simpleMatrix.mValues[Matrix.MTRANS_X] = 0;
+ simpleMatrix.mValues[Matrix.MTRANS_Y] = 0;
for (int i = 0; i < vectorCount; i++) {
final PointF mapped = mapPoint(src[srcIndex + i * 2], src[srcIndex + i * 2 + 1]);
@@ -325,25 +345,43 @@ public class ShadowMatrix {
dst[dstIndex + i * 2 + 1] = mapped.y;
}
- mMatrix.mValues[Matrix.MTRANS_X] = transX;
- mMatrix.mValues[Matrix.MTRANS_Y] = transY;
+ simpleMatrix.mValues[Matrix.MTRANS_X] = transX;
+ simpleMatrix.mValues[Matrix.MTRANS_Y] = transY;
+ }
+
+ @Implementation
+ protected float mapRadius(float radius) {
+ float[] src = new float[] {radius, 0.f, 0.f, radius};
+ mapVectors(src, 0, src, 0, 2);
+
+ float l1 = (float) Math.hypot(src[0], src[1]);
+ float l2 = (float) Math.hypot(src[2], src[3]);
+ return (float) Math.sqrt(l1 * l2);
+ }
+
+ @Implementation
+ protected boolean setRectToRect(RectF src, RectF dst, Matrix.ScaleToFit stf) {
+ if (src.isEmpty()) {
+ reset();
+ return false;
+ }
+ return simpleMatrix.setRectToRect(src, dst, stf);
}
@Implementation
@Override
public boolean equals(Object obj) {
- final float[] values;
if (obj instanceof Matrix) {
- return getSimpleMatrix(((Matrix) obj)).equals(mMatrix);
+ return getSimpleMatrix(((Matrix) obj)).equals(simpleMatrix);
} else {
- return obj instanceof ShadowMatrix && obj.equals(mMatrix);
+ return obj instanceof ShadowMatrix && obj.equals(simpleMatrix);
}
}
@Implementation(minSdk = KITKAT)
@Override
public int hashCode() {
- return Objects.hashCode(mMatrix);
+ return Objects.hashCode(simpleMatrix);
}
public String getDescription() {
@@ -352,16 +390,16 @@ public class ShadowMatrix {
private static SimpleMatrix getSimpleMatrix(Matrix matrix) {
final ShadowMatrix otherMatrix = Shadow.extract(matrix);
- return otherMatrix.mMatrix;
+ return otherMatrix.simpleMatrix;
}
private boolean postConcat(SimpleMatrix matrix) {
- mMatrix = matrix.multiply(mMatrix);
+ simpleMatrix = matrix.multiply(simpleMatrix);
return true;
}
private boolean preConcat(SimpleMatrix matrix) {
- mMatrix = mMatrix.multiply(matrix);
+ simpleMatrix = simpleMatrix.multiply(matrix);
return true;
}
@@ -369,11 +407,16 @@ public class ShadowMatrix {
* A simple implementation of an immutable matrix.
*/
private static class SimpleMatrix {
- private static final SimpleMatrix IDENTITY = new SimpleMatrix(new float[] {
- 1.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 1.0f,
- });
+ private static final SimpleMatrix IDENTITY = newIdentityMatrix();
+
+ private static SimpleMatrix newIdentityMatrix() {
+ return new SimpleMatrix(
+ new float[] {
+ 1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f,
+ });
+ }
private final float[] mValues;
@@ -517,6 +560,62 @@ public class ShadowMatrix {
point.x * mValues[3] + point.y * mValues[4] + mValues[5]);
}
+ // See: https://android.googlesource.com/platform/frameworks/base/+/6fca81de9b2079ec88e785f58bf49bf1f0c105e2/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+ protected boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) {
+ if (dst.isEmpty()) {
+ mValues[0] =
+ mValues[1] =
+ mValues[2] = mValues[3] = mValues[4] = mValues[5] = mValues[6] = mValues[7] = 0;
+ mValues[8] = 1;
+ } else {
+ float tx = dst.width() / src.width();
+ float sx = dst.width() / src.width();
+ float ty = dst.height() / src.height();
+ float sy = dst.height() / src.height();
+ boolean xLarger = false;
+
+ if (stf != ScaleToFit.FILL) {
+ if (sx > sy) {
+ xLarger = true;
+ sx = sy;
+ } else {
+ sy = sx;
+ }
+ }
+
+ tx = dst.left - src.left * sx;
+ ty = dst.top - src.top * sy;
+ if (stf == ScaleToFit.CENTER || stf == ScaleToFit.END) {
+ float diff;
+
+ if (xLarger) {
+ diff = dst.width() - src.width() * sy;
+ } else {
+ diff = dst.height() - src.height() * sy;
+ }
+
+ if (stf == ScaleToFit.CENTER) {
+ diff = diff / 2;
+ }
+
+ if (xLarger) {
+ tx += diff;
+ } else {
+ ty += diff;
+ }
+ }
+
+ mValues[0] = sx;
+ mValues[4] = sy;
+ mValues[2] = tx;
+ mValues[5] = ty;
+ mValues[1] = mValues[3] = mValues[6] = mValues[7] = 0;
+ }
+ // shared cleanup
+ mValues[8] = 1;
+ return true;
+ }
+
@Override
public boolean equals(Object o) {
return this == o || (o instanceof SimpleMatrix && equals((SimpleMatrix) o));
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaMetadataRetriever.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaMetadataRetriever.java
index 1f044c25a..0d17e8812 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaMetadataRetriever.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaMetadataRetriever.java
@@ -31,27 +31,27 @@ public class ShadowMediaMetadataRetriever {
}
@Implementation
- public void setDataSource(String path) {
+ protected void setDataSource(String path) {
setDataSource(toDataSource(path));
}
@Implementation
- public void setDataSource(Context context, Uri uri) {
+ protected void setDataSource(Context context, Uri uri) {
setDataSource(toDataSource(context, uri));
}
@Implementation
- public void setDataSource(String uri, Map<String, String> headers) {
+ protected void setDataSource(String uri, Map<String, String> headers) {
setDataSource(toDataSource(uri, headers));
}
@Implementation
- public void setDataSource(FileDescriptor fd, long offset, long length) {
+ protected void setDataSource(FileDescriptor fd, long offset, long length) {
setDataSource(toDataSource(fd, offset, length));
}
@Implementation
- public String extractMetadata(int keyCode) {
+ protected String extractMetadata(int keyCode) {
if (metadata.containsKey(dataSource)) {
return metadata.get(dataSource).get(keyCode);
}
@@ -59,7 +59,7 @@ public class ShadowMediaMetadataRetriever {
}
@Implementation
- public Bitmap getFrameAtTime(long timeUs, int option) {
+ protected Bitmap getFrameAtTime(long timeUs, int option) {
return (frames.containsKey(dataSource) ?
frames.get(dataSource).get(timeUs) : null);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaPlayer.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaPlayer.java
index 1614031fb..6e6c93896 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaPlayer.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaPlayer.java
@@ -42,11 +42,11 @@ import org.robolectric.shadows.util.DataSource;
* testing that your code properly handles asynchronous errors and events. This
* near impossible task is made quite straightforward using this implementation
* of {@link MediaPlayer} with Robolectric.
- *
+ *
* This shadow implementation provides much of the functionality needed to
* emulate {@link MediaPlayer} initialization and playback behavior without having
* to play actual media files. A summary of the features included are:
- *
+ *
* * Construction-time callback hook {@link CreateListener} so that
* newly-created {@link MediaPlayer} instances can have their shadows configured
* before they are used.
@@ -78,31 +78,31 @@ import org.robolectric.shadows.util.DataSource;
* {@link #addMediaInfo(DataSource, MediaInfo)} respectively) <i>before</i>
* calling {@link #setDataSource}, otherwise you'll get an
* {@link IllegalArgumentException}.
- *
+ *
* The current features of {@code ShadowMediaPlayer} were focused on development
* for testing playback of audio tracks. Thus support for emulating timed text and
* video events is incomplete. None of these features would be particularly onerous
* to add/fix - contributions welcome, of course!
- *
+ *
* @author Fr Jeremy Krieg, Holy Monastery of St Nectarios, Adelaide, Australia
*/
@Implements(MediaPlayer.class)
public class ShadowMediaPlayer extends ShadowPlayerBase {
@Implementation
- public static void __staticInitializer__() {
+ protected static void __staticInitializer__() {
// don't bind the JNI library
}
/**
* Listener that is called when a new MediaPlayer is constructed.
- *
+ *
* @see #setCreateListener(CreateListener)
*/
protected static CreateListener createListener;
private static final Map<DataSource, Exception> exceptions = new HashMap<>();
private static final Map<DataSource, MediaInfo> mediaInfo = new HashMap<>();
-
+
@RealObject
private MediaPlayer player;
@@ -117,7 +117,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Possible behavior modes for the media player when a method is invoked in an
* invalid state.
- *
+ *
* @see #setInvalidStateBehavior
*/
public enum InvalidStateBehavior {
@@ -154,7 +154,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
public interface MediaEvent {
public void run(MediaPlayer mp, ShadowMediaPlayer smp);
}
-
+
/**
* Class specifying information for an emulated media object. Used by
* ShadowMediaPlayer when setDataSource() is called to populate the shadow
@@ -174,12 +174,12 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
public MediaInfo() {
this(1000, 0);
}
-
+
/**
* Creates a new {@code MediaInfo} object with the given duration and
* preparation delay. A completion callback event is scheduled at
* {@code duration} ms from the end.
- *
+ *
* @param duration
* the duration (in ms) of this emulated media. A callback event
* will be scheduled at this offset to stop playback simulation and
@@ -199,7 +199,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Retrieves the current preparation delay for this media.
- *
+ *
* @return The current preparation delay (in ms).
*/
public int getPreparationDelay() {
@@ -208,7 +208,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Sets the current preparation delay for this media.
- *
+ *
* @param preparationDelay
* the new preparation delay (in ms).
*/
@@ -220,7 +220,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* Schedules a generic event to run at the specified playback offset. Events
* are run on the thread on which the {@link android.media.MediaPlayer
* MediaPlayer} was created.
- *
+ *
* @param offset
* the offset from the start of playback at which this event will
* run.
@@ -242,7 +242,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* Schedules an error event to run at the specified playback offset. A
* reference to the actual MediaEvent that is scheduled is returned, which can
* be used in a subsequent call to {@link #removeEventAtOffset}.
- *
+ *
* @param offset
* the offset from the start of playback at which this error will
* trigger.
@@ -266,7 +266,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* Schedules an info event to run at the specified playback offset. A
* reference to the actual MediaEvent that is scheduled is returned, which can
* be used in a subsequent call to {@link #removeEventAtOffset}.
- *
+ *
* @param offset
* the offset from the start of playback at which this event will
* trigger.
@@ -297,7 +297,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* playback offset. A reference to the actual MediaEvent that is scheduled is
* returned, which can be used in a subsequent call to
* {@link #removeEventAtOffset}.
- *
+ *
* This event will issue an {@link MediaPlayer.OnInfoListener#onInfo
* onInfo()} callback with {@link MediaPlayer#MEDIA_INFO_BUFFERING_START} to
* signal the start of buffering and then call {@link #doStop()} to
@@ -305,7 +305,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* after {@code length} ms which fires a
* {@link MediaPlayer#MEDIA_INFO_BUFFERING_END} info event and invokes
* {@link #doStart()} to resume playback.
- *
+ *
* @param offset
* the offset from the start of playback at which this underrun
* will trigger.
@@ -336,7 +336,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Removes the specified event from the playback schedule at the given
* playback offset.
- *
+ *
* @param offset
* the offset at which the event was scheduled.
* @param event
@@ -356,7 +356,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Removes the specified event from the playback schedule at all playback
* offsets where it has been scheduled.
- *
+ *
* @param event
* the event to remove.
* @see ShadowMediaPlayer.MediaInfo#removeEventAtOffset(int,ShadowMediaPlayer.MediaEvent)
@@ -378,16 +378,16 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
Message msg = handler.obtainMessage(MEDIA_EVENT, e);
handler.sendMessage(msg);
}
-
+
public void postEventDelayed(MediaEvent e, long delay) {
Message msg = handler.obtainMessage(MEDIA_EVENT, e);
handler.sendMessageDelayed(msg, delay);
}
-
+
/**
* Callback interface for clients that wish to be informed when a new
* {@link MediaPlayer} instance is constructed.
- *
+ *
* @see #setCreateListener
*/
public static interface CreateListener {
@@ -395,7 +395,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* Method that is invoked when a new {@link MediaPlayer} is created. This
* method is invoked at the end of the constructor, after all of the default
* setup has been completed.
- *
+ *
* @param player
* reference to the newly-created media player object.
* @param shadow
@@ -504,7 +504,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
}
@Implementation
- public static MediaPlayer create(Context context, int resId) {
+ protected static MediaPlayer create(Context context, int resId) {
MediaPlayer mp = new MediaPlayer();
ShadowMediaPlayer shadow = Shadow.extract(mp);
shadow.sourceResId = resId;
@@ -520,7 +520,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
}
@Implementation
- public static MediaPlayer create(Context context, Uri uri) {
+ protected static MediaPlayer create(Context context, Uri uri) {
MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource(context, uri);
@@ -533,7 +533,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
}
@Implementation
- public void __constructor__() {
+ protected void __constructor__() {
// Contract of audioSessionId is that if it is 0 (which represents
// the master mix) then that's an error. By default it generates
// an ID that is unique system-wide. We could simulate guaranteed
@@ -583,7 +583,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* Usually this method would not be called directly, but indirectly through one of the
* other {@link #setDataSource(String)} implementations, which use {@link DataSource#toDataSource(String)}
* methods to convert their discrete parameters into a single {@link DataSource} instance.
- *
+ *
* @param dataSource the data source that is being set.
* @throws IOException if the specified data source has been configured to throw an IO exception.
* @see #addException(DataSource, IOException)
@@ -605,14 +605,14 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
doSetDataSource(dataSource);
state = INITIALIZED;
}
-
+
/**
* Sets the data source without doing any other emulation. Sets the
* internal data source only.
* Calling directly can be useful for setting up a {@link ShadowMediaPlayer}
* instance during specific testing so that you don't have to clutter your
* tests catching exceptions you know won't be thrown.
- *
+ *
* @param dataSource the data source that is being set.
* @see #setDataSource(DataSource)
*/
@@ -623,51 +623,52 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
}
this.dataSource = dataSource;
}
-
+
@Implementation
- public void setDataSource(String path) throws IOException {
+ protected void setDataSource(String path) throws IOException {
setDataSource(toDataSource(path));
}
@Implementation
- public void setDataSource(Context context, Uri uri, Map<String, String> headers) throws IOException {
+ protected void setDataSource(Context context, Uri uri, Map<String, String> headers)
+ throws IOException {
setDataSource(toDataSource(context, uri, headers));
sourceUri = uri;
}
@Implementation
- public void setDataSource(String uri, Map<String, String> headers) throws IOException {
+ protected void setDataSource(String uri, Map<String, String> headers) throws IOException {
setDataSource(toDataSource(uri, headers));
}
@Implementation
- public void setDataSource(FileDescriptor fd, long offset, long length) throws IOException {
+ protected void setDataSource(FileDescriptor fd, long offset, long length) throws IOException {
setDataSource(toDataSource(fd, offset, length));
}
public static MediaInfo getMediaInfo(DataSource dataSource) {
return mediaInfo.get(dataSource);
}
-
+
public static void addMediaInfo(DataSource dataSource, MediaInfo info) {
mediaInfo.put(dataSource, info);
}
-
+
public static void addException(DataSource dataSource, RuntimeException e) {
exceptions.put(dataSource, e);
}
-
+
public static void addException(DataSource dataSource, IOException e) {
exceptions.put(dataSource, e);
}
-
+
/**
* Checks states for methods that only log when there is an error. Such
* methods throw an {@link IllegalArgumentException} when invoked in the END
* state, but log an error in other disallowed states. This method will either
* emulate this behavior or else will generate an assertion if invoked from a
* disallowed state if {@link #setAssertOnError assertOnError} is set.
- *
+ *
* @param method
* the name of the method being tested.
* @param allowedStates
@@ -678,19 +679,19 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
*/
private void checkStateLog(String method, EnumSet<State> allowedStates) {
switch (invalidStateBehavior) {
- case SILENT:
- break;
- case EMULATE:
- if (state == END) {
- String msg = "Can't call " + method + " from state " + state;
- throw new IllegalStateException(msg);
- }
- break;
- case ASSERT:
- if (!allowedStates.contains(state) || state == END) {
- String msg = "Can't call " + method + " from state " + state;
- throw new AssertionError(msg);
- }
+ case SILENT:
+ break;
+ case EMULATE:
+ if (state == END) {
+ String msg = "Can't call " + method + " from state " + state;
+ throw new IllegalStateException(msg);
+ }
+ break;
+ case ASSERT:
+ if (!allowedStates.contains(state) || state == END) {
+ String msg = "Can't call " + method + " from state " + state;
+ throw new AssertionError(msg);
+ }
}
}
@@ -700,13 +701,13 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* onError()} when invoked in an illegal state. Such methods always throw
* {@link IllegalStateException} rather than invoke {@code onError()} if
* they are invoked from the END state.
- *
+ *
* This method will either emulate this behavior by posting an
* {@code onError()} callback to the current thread's message queue (or
* throw an {@link IllegalStateException} if invoked from the END state), or
* else it will generate an assertion if {@link #setAssertOnError
* assertOnError} is set.
- *
+ *
* @param method
* the name of the method being tested.
* @param allowedStates
@@ -719,19 +720,19 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
private boolean checkStateError(String method, EnumSet<State> allowedStates) {
if (!allowedStates.contains(state)) {
switch (invalidStateBehavior) {
- case SILENT:
- break;
- case EMULATE:
- if (state == END) {
+ case SILENT:
+ break;
+ case EMULATE:
+ if (state == END) {
+ String msg = "Can't call " + method + " from state " + state;
+ throw new IllegalStateException(msg);
+ }
+ state = ERROR;
+ postEvent(invalidStateErrorCallback);
+ return false;
+ case ASSERT:
String msg = "Can't call " + method + " from state " + state;
- throw new IllegalStateException(msg);
- }
- state = ERROR;
- postEvent(invalidStateErrorCallback);
- return false;
- case ASSERT:
- String msg = "Can't call " + method + " from state " + state;
- throw new AssertionError(msg);
+ throw new AssertionError(msg);
}
}
return true;
@@ -743,7 +744,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* {@link IllegalArgumentException} if it determines that the method has been
* invoked from a disallowed state, or else it will generate an assertion if
* {@link #setAssertOnError assertOnError} is set.
- *
+ *
* @param method
* the name of the method being tested.
* @param allowedStates
@@ -756,44 +757,43 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
if (!allowedStates.contains(state)) {
String msg = "Can't call " + method + " from state " + state;
switch (invalidStateBehavior) {
- case SILENT:
- break;
- case EMULATE:
- throw new IllegalStateException(msg);
- case ASSERT:
- throw new AssertionError(msg);
+ case SILENT:
+ break;
+ case EMULATE:
+ throw new IllegalStateException(msg);
+ case ASSERT:
+ throw new AssertionError(msg);
}
}
}
@Implementation
- public void setOnCompletionListener(MediaPlayer.OnCompletionListener listener) {
+ protected void setOnCompletionListener(MediaPlayer.OnCompletionListener listener) {
completionListener = listener;
}
@Implementation
- public void setOnSeekCompleteListener(
- MediaPlayer.OnSeekCompleteListener listener) {
+ protected void setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener listener) {
seekCompleteListener = listener;
}
@Implementation
- public void setOnPreparedListener(MediaPlayer.OnPreparedListener listener) {
+ protected void setOnPreparedListener(MediaPlayer.OnPreparedListener listener) {
preparedListener = listener;
}
@Implementation
- public void setOnInfoListener(MediaPlayer.OnInfoListener listener) {
+ protected void setOnInfoListener(MediaPlayer.OnInfoListener listener) {
infoListener = listener;
}
@Implementation
- public void setOnErrorListener(MediaPlayer.OnErrorListener listener) {
+ protected void setOnErrorListener(MediaPlayer.OnErrorListener listener) {
errorListener = listener;
}
@Implementation
- public boolean isLooping() {
+ protected boolean isLooping() {
checkStateException("isLooping()", nonEndStates);
return looping;
}
@@ -804,20 +804,20 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
.complementOf(EnumSet.of(ERROR, END));
@Implementation
- public void setLooping(boolean looping) {
+ protected void setLooping(boolean looping) {
checkStateError("setLooping()", nonErrorStates);
this.looping = looping;
}
@Implementation
- public void setVolume(float left, float right) {
+ protected void setVolume(float left, float right) {
checkStateError("setVolume()", nonErrorStates);
leftVolume = left;
rightVolume = right;
}
@Implementation
- public boolean isPlaying() {
+ protected boolean isPlaying() {
checkStateError("isPlaying()", nonErrorStates);
return state == STARTED;
}
@@ -826,19 +826,17 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
STOPPED);
/**
- * Simulates {@link MediaPlayer#prepareAsync()}. Sleeps for
- * {@link MediaInfo#getPreparationDelay() preparationDelay} ms by calling
- * {@link SystemClock#sleep(long)} before calling
- * {@link #invokePreparedListener()}.
- *
- * If {@code preparationDelay} is not positive and non-zero, there is no
- * sleep.
- *
+ * Simulates {@link MediaPlayer#prepareAsync()}. Sleeps for {@link MediaInfo#getPreparationDelay()
+ * preparationDelay} ms by calling {@link SystemClock#sleep(long)} before calling {@link
+ * #invokePreparedListener()}.
+ *
+ * <p>If {@code preparationDelay} is not positive and non-zero, there is no sleep.
+ *
* @see MediaInfo#setPreparationDelay(int)
* @see #invokePreparedListener()
*/
@Implementation
- public void prepare() {
+ protected void prepare() {
checkStateException("prepare()", preparableStates);
MediaInfo info = getMediaInfo();
if (info.preparationDelay > 0) {
@@ -848,17 +846,16 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
}
/**
- * Simulates {@link MediaPlayer#prepareAsync()}. Sets state to PREPARING and
- * posts a callback to {@link #invokePreparedListener()} if the current
- * preparation delay for the current media (see {@link #getMediaInfo()}) is &gt;=
- * 0, otherwise the test suite is responsible for calling
- * {@link #invokePreparedListener()} directly if required.
- *
+ * Simulates {@link MediaPlayer#prepareAsync()}. Sets state to PREPARING and posts a callback to
+ * {@link #invokePreparedListener()} if the current preparation delay for the current media (see
+ * {@link #getMediaInfo()}) is &gt;= 0, otherwise the test suite is responsible for calling {@link
+ * #invokePreparedListener()} directly if required.
+ *
* @see MediaInfo#setPreparationDelay(int)
* @see #invokePreparedListener()
*/
@Implementation
- public void prepareAsync() {
+ protected void prepareAsync() {
checkStateException("prepareAsync()", preparableStates);
state = PREPARING;
MediaInfo info = getMediaInfo();
@@ -873,14 +870,14 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Simulates private native method {@link MediaPlayer#_start()}. Sets state to STARTED and calls
* {@link #doStart()} to start scheduling playback callback events.
- *
- * If the current state is PLAYBACK_COMPLETED, the current position is reset
- * to zero before starting playback.
- *
+ *
+ * <p>If the current state is PLAYBACK_COMPLETED, the current position is reset to zero before
+ * starting playback.
+ *
* @see #doStart()
*/
@Implementation
- public void start() {
+ protected void start() {
if (checkStateError("start()", startableStates)) {
if (state == PLAYBACK_COMPLETED) {
startOffset = 0;
@@ -911,14 +908,14 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Tests to see if the player is really playing.
- *
+ *
* The player is defined as "really playing" if simulated playback events
* (including playback completion) are being scheduled and invoked and
* {@link #getCurrentPosition currentPosition} is being updated as time
* passes. Note that while the player will normally be really playing if in
* the STARTED state, this is not always the case - for example, if a pending
* seek is in progress, or perhaps a buffer underrun is being simulated.
- *
+ *
* @return {@code true} if the player is really playing or
* {@code false} if the player is internally paused.
* @see #doStart
@@ -932,7 +929,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* Starts simulated playback. Until this method is called, the player is not
* "really playing" (see {@link #isReallyPlaying} for a definition of
* "really playing").
- *
+ *
* This method is used internally by the various shadow method implementations
* of the MediaPlayer public API, but may also be called directly by the test
* suite if you wish to simulate an internal pause. For example, to simulate
@@ -942,7 +939,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* end and restart normal playback (which is what
* {@link ShadowMediaPlayer.MediaInfo#scheduleBufferUnderrunAtOffset(int, int) scheduleBufferUnderrunAtOffset()}
* does).
- *
+ *
* @see #isReallyPlaying()
* @see #doStop()
*/
@@ -955,11 +952,11 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* Pauses simulated playback. After this method is called, the player is no
* longer "really playing" (see {@link #isReallyPlaying} for a definition of
* "really playing").
- *
+ *
* This method is used internally by the various shadow method implementations
* of the MediaPlayer public API, but may also be called directly by the test
* suite if you wish to simulate an internal pause.
- *
+ *
* @see #isReallyPlaying()
* @see #doStart()
*/
@@ -976,13 +973,13 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
PAUSED, PLAYBACK_COMPLETED);
/**
- * Simulates {@link MediaPlayer#_pause()}. Invokes {@link #doStop()} to suspend
- * playback event callbacks and sets the state to PAUSED.
- *
+ * Simulates {@link MediaPlayer#_pause()}. Invokes {@link #doStop()} to suspend playback event
+ * callbacks and sets the state to PAUSED.
+ *
* @see #doStop()
*/
@Implementation
- public void _pause() {
+ protected void _pause() {
if (checkStateError("pause()", pausableStates)) {
doStop();
state = PAUSED;
@@ -992,11 +989,11 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
static final EnumSet<State> allStates = EnumSet.allOf(State.class);
/**
- * Simulates call to {@link MediaPlayer#_release()}. Calls {@link #doStop()} to
- * suspend playback event callbacks and sets the state to END.
+ * Simulates call to {@link MediaPlayer#_release()}. Calls {@link #doStop()} to suspend playback
+ * event callbacks and sets the state to END.
*/
@Implementation
- public void _release() {
+ protected void _release() {
checkStateException("release()", allStates);
doStop();
state = END;
@@ -1004,11 +1001,11 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
}
/**
- * Simulates call to {@link MediaPlayer#_reset()}. Calls {@link #doStop()} to
- * suspend playback event callbacks and sets the state to IDLE.
+ * Simulates call to {@link MediaPlayer#_reset()}. Calls {@link #doStop()} to suspend playback
+ * event callbacks and sets the state to IDLE.
*/
@Implementation
- public void _reset() {
+ protected void _reset() {
checkStateException("reset()", nonEndStates);
doStop();
state = IDLE;
@@ -1020,11 +1017,11 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
STARTED, PAUSED, STOPPED, PLAYBACK_COMPLETED);
/**
- * Simulates call to {@link MediaPlayer#release()}. Calls {@link #doStop()} to
- * suspend playback event callbacks and sets the state to STOPPED.
+ * Simulates call to {@link MediaPlayer#release()}. Calls {@link #doStop()} to suspend playback
+ * event callbacks and sets the state to STOPPED.
*/
@Implementation
- public void _stop() {
+ protected void _stop() {
if (checkStateError("stop()", stoppableStates)) {
doStop();
state = STOPPED;
@@ -1036,52 +1033,52 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
PLAYBACK_COMPLETED);
@Implementation
- public void attachAuxEffect(int effectId) {
+ protected void attachAuxEffect(int effectId) {
checkStateError("attachAuxEffect()", attachableStates);
auxEffect = effectId;
}
@Implementation
- public int getAudioSessionId() {
+ protected int getAudioSessionId() {
checkStateException("getAudioSessionId()", allStates);
return audioSessionId;
}
/**
- * Simulates call to {@link MediaPlayer#getCurrentPosition()}. Simply does the
- * state validity checks and then invokes {@link #getCurrentPositionRaw()} to
- * calculate the simulated playback position.
- *
+ * Simulates call to {@link MediaPlayer#getCurrentPosition()}. Simply does the state validity
+ * checks and then invokes {@link #getCurrentPositionRaw()} to calculate the simulated playback
+ * position.
+ *
* @return The current offset (in ms) of the simulated playback.
* @see #getCurrentPositionRaw()
*/
@Implementation
- public int getCurrentPosition() {
+ protected int getCurrentPosition() {
checkStateError("getCurrentPosition()", attachableStates);
return getCurrentPositionRaw();
}
/**
- * Simulates call to {@link MediaPlayer#getDuration()}. Retrieves the duration
- * as defined by the current {@link MediaInfo} instance.
- *
+ * Simulates call to {@link MediaPlayer#getDuration()}. Retrieves the duration as defined by the
+ * current {@link MediaInfo} instance.
+ *
* @return The duration (in ms) of the current simulated playback.
* @see #addMediaInfo(DataSource, MediaInfo)
*/
@Implementation
- public int getDuration() {
+ protected int getDuration() {
checkStateError("getDuration()", stoppableStates);
return getMediaInfo().duration;
}
@Implementation
- public int getVideoHeight() {
+ protected int getVideoHeight() {
checkStateLog("getVideoHeight()", attachableStates);
return videoHeight;
}
@Implementation
- public int getVideoWidth() {
+ protected int getVideoWidth() {
checkStateLog("getVideoWidth()", attachableStates);
return videoWidth;
}
@@ -1090,16 +1087,14 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
STARTED, PAUSED, PLAYBACK_COMPLETED);
/**
- * Simulates seeking to specified position. The seek will complete after
- * {@link #seekDelay} ms (defaults to 0), or else if seekDelay is negative
- * then the controlling test is expected to simulate seek completion by
- * manually invoking {@link #invokeSeekCompleteListener}.
- *
- * @param seekTo
- * the offset (in ms) from the start of the track to seek to.
+ * Simulates seeking to specified position. The seek will complete after {@link #seekDelay} ms
+ * (defaults to 0), or else if seekDelay is negative then the controlling test is expected to
+ * simulate seek completion by manually invoking {@link #invokeSeekCompleteListener}.
+ *
+ * @param seekTo the offset (in ms) from the start of the track to seek to.
*/
@Implementation
- public void seekTo(int seekTo) {
+ protected void seekTo(int seekTo) {
seekTo(seekTo, MediaPlayer.SEEK_PREVIOUS_SYNC);
}
@@ -1125,7 +1120,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
static private final EnumSet<State> idleState = EnumSet.of(IDLE);
@Implementation
- public void setAudioSessionId(int sessionId) {
+ protected void setAudioSessionId(int sessionId) {
checkStateError("setAudioSessionId()", idleState);
audioSessionId = sessionId;
}
@@ -1134,7 +1129,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
INITIALIZED, STOPPED);
@Implementation
- public void setAudioStreamType(int audioStreamType) {
+ protected void setAudioStreamType(int audioStreamType) {
checkStateError("setAudioStreamType()", nonPlayingStates);
this.audioStreamType = audioStreamType;
}
@@ -1151,7 +1146,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* is invoked soon after, without a break in the code. Using this callback
* means you don't have to change this common pattern just so that you can
* customize the shadow for testing.
- *
+ *
* @param createListener
* the listener to be invoked
*/
@@ -1168,7 +1163,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* offset (no matter how long playback may be paused for, or where you seek
* to, etc), see {@link MediaInfo#scheduleEventAtOffset(int, ShadowMediaPlayer.MediaEvent)} and
* its various helpers.
- *
+ *
* @return Handler object that can be used to schedule asynchronous events on
* this media player.
*/
@@ -1181,7 +1176,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* method is invoked in an invalid state. See
* {@link #setInvalidStateBehavior(InvalidStateBehavior)} for a discussion of
* the available modes and their associated behaviors.
- *
+ *
* @return The current invalid state behavior mode.
* @see #setInvalidStateBehavior
*/
@@ -1220,7 +1215,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
*
* Additionally, all three methods behave synchronously (throwing
* {@link IllegalStateException} when invoked from the END state.
- *
+ *
* To complicate matters slightly, the official documentation sometimes
* contradicts observed behavior. For example, the documentation says it is
* illegal to call {@link #setDataSource} from the ERROR state - however, in
@@ -1252,7 +1247,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* Retrieves the currently selected {@link MediaInfo}. This instance is used
* to define current duration, preparation delay, exceptions for
* {@code setDataSource()}, playback events, etc.
- *
+ *
* @return The currently selected {@link MediaInfo}.
* @see #addMediaInfo
* @see #doSetDataSource(DataSource)
@@ -1264,7 +1259,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Sets the current position, bypassing the normal state checking. Use with
* care.
- *
+ *
* @param position
* the new playback position.
*/
@@ -1275,7 +1270,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Retrieves the current position without doing the state checking that the
* emulated version of {@link #getCurrentPosition()} does.
- *
+ *
* @return The current playback position within the current clip.
*/
public int getCurrentPositionRaw() {
@@ -1289,7 +1284,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Retrieves the current duration without doing the state checking that the
* emulated version does.
- *
+ *
* @return The duration of the current clip loaded by the player.
*/
public int getDurationRaw() {
@@ -1299,7 +1294,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Retrieves the current state of the {@link MediaPlayer}. Uses the states as
* defined in the {@link MediaPlayer} documentation.
- *
+ *
* @return The current state of the {@link MediaPlayer}, as defined in the
* MediaPlayer documentation.
* @see #setState
@@ -1312,11 +1307,11 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Forces the @link MediaPlayer} into the specified state. Uses the states as
* defined in the {@link MediaPlayer} documentation.
- *
+ *
* Note that by invoking this method directly you can get the player into an
* inconsistent state that a real player could not be put in (eg, in the END
* state but with playback events still happening). Use with care.
- *
+ *
* @param state
* the new state of the {@link MediaPlayer}, as defined in the
* MediaPlayer documentation.
@@ -1335,7 +1330,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* it should be annotated with {@link Implementation}, because
* there is a private method in the later API versions with
* the same name, however this would fail on earlier versions.
- *
+ *
* @return audioStreamType
*/
public int getTheAudioStreamType() {
@@ -1354,7 +1349,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* Default is 0. If set to -1, then seekTo() will not call the
* OnSeekCompleteListener automatically; you will need to call
* invokeSeekCompleteListener() manually.
- *
+ *
* @param seekDelay
* length of time to delay (ms)
*/
@@ -1364,7 +1359,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Useful for assertions.
- *
+ *
* @return The current {@code auxEffect} setting.
*/
public int getAuxEffect() {
@@ -1373,7 +1368,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Retrieves the pending seek setting.
- *
+ *
* @return The position to which the shadow player is seeking for the seek in
* progress (ie, after the call to {@link #seekTo} but before a call
* to {@link #invokeSeekCompleteListener()}). Returns {@code -1}
@@ -1386,9 +1381,9 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Retrieves the data source (if any) that was passed in to
* {@link #setDataSource(DataSource)}.
- *
+ *
* Useful for assertions.
- *
+ *
* @return The source passed in to {@code setDataSource}.
*/
public DataSource getDataSource() {
@@ -1399,7 +1394,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* Retrieves the source path (if any) that was passed in to
* {@link MediaPlayer#setDataSource(Context, Uri, Map)} or
* {@link MediaPlayer#setDataSource(Context, Uri)}.
- *
+ *
* @return The source Uri passed in to {@code setDataSource}.
*/
public Uri getSourceUri() {
@@ -1409,7 +1404,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Retrieves the resource ID used in the call to {@link #create(Context, int)}
* (if any).
- *
+ *
* @return The resource ID passed in to {@code create()}, or
* {@code -1} if a different method of setting the source was
* used.
@@ -1441,7 +1436,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
* Tests to see if the player is in the PREPARED state.
* This is mainly used for backward compatibility.
* {@link #getState} may be more useful for new testing applications.
- *
+ *
* @return {@code true} if the MediaPlayer is in the PREPARED state,
* false otherwise.
*/
@@ -1507,7 +1502,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Allows test cases to directly simulate invocation of the OnInfo event.
- *
+ *
* @param what
* parameter to pass in to {@code what} in
* {@link MediaPlayer.OnInfoListener#onInfo(MediaPlayer, int, int)}.
@@ -1523,7 +1518,7 @@ public class ShadowMediaPlayer extends ShadowPlayerBase {
/**
* Allows test cases to directly simulate invocation of the OnError event.
- *
+ *
* @param what
* parameter to pass in to {@code what} in
* {@link MediaPlayer.OnErrorListener#onError(MediaPlayer, int, int)}.
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaRecorder.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaRecorder.java
index 7dc410dc9..c70ca98d5 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaRecorder.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaRecorder.java
@@ -10,7 +10,7 @@ import org.robolectric.annotation.Implements;
public class ShadowMediaRecorder {
@SuppressWarnings("UnusedDeclaration")
@Implementation
- public static void __staticInitializer__() {
+ protected static void __staticInitializer__() {
// don't bind the JNI library
}
@@ -48,132 +48,132 @@ public class ShadowMediaRecorder {
private MediaRecorder.OnInfoListener infoListener;
@Implementation
- public void __constructor__() {
+ protected void __constructor__() {
state = STATE_INITIAL;
}
@Implementation
- public void setAudioChannels(int numChannels) {
+ protected void setAudioChannels(int numChannels) {
audioChannels = numChannels;
}
@Implementation
- public void setAudioEncoder(int audio_encoder) {
+ protected void setAudioEncoder(int audio_encoder) {
audioEncoder = audio_encoder;
state = STATE_DATA_SOURCE_CONFIGURED;
}
@Implementation
- public void setAudioEncodingBitRate(int bitRate) {
+ protected void setAudioEncodingBitRate(int bitRate) {
audioBitRate = bitRate;
}
@Implementation
- public void setAudioSamplingRate(int samplingRate) {
+ protected void setAudioSamplingRate(int samplingRate) {
audioSamplingRate = samplingRate;
}
@Implementation
- public void setAudioSource(int audio_source) {
+ protected void setAudioSource(int audio_source) {
audioSource = audio_source;
state = STATE_INITIALIZED;
}
@Implementation
- public void setCamera(Camera c) {
+ protected void setCamera(Camera c) {
camera = c;
}
@Implementation
- public void setMaxDuration(int max_duration_ms) {
+ protected void setMaxDuration(int max_duration_ms) {
maxDuration = max_duration_ms;
}
@Implementation
- public void setMaxFileSize(long max_filesize_bytes) {
+ protected void setMaxFileSize(long max_filesize_bytes) {
maxFileSize = max_filesize_bytes;
}
@Implementation
- public void setOnErrorListener(MediaRecorder.OnErrorListener l) {
+ protected void setOnErrorListener(MediaRecorder.OnErrorListener l) {
errorListener = l;
}
@Implementation
- public void setOnInfoListener(MediaRecorder.OnInfoListener listener) {
+ protected void setOnInfoListener(MediaRecorder.OnInfoListener listener) {
infoListener = listener;
}
@Implementation
- public void setOutputFile(String path) {
+ protected void setOutputFile(String path) {
outputPath = path;
state = STATE_DATA_SOURCE_CONFIGURED;
}
@Implementation
- public void setOutputFormat(int output_format) {
+ protected void setOutputFormat(int output_format) {
outputFormat = output_format;
state = STATE_DATA_SOURCE_CONFIGURED;
}
@Implementation
- public void setPreviewDisplay(Surface sv) {
+ protected void setPreviewDisplay(Surface sv) {
previewDisplay = sv;
state = STATE_DATA_SOURCE_CONFIGURED;
}
@Implementation
- public void setVideoEncoder(int video_encoder) {
+ protected void setVideoEncoder(int video_encoder) {
videoEncoder = video_encoder;
state = STATE_DATA_SOURCE_CONFIGURED;
}
@Implementation
- public void setVideoEncodingBitRate(int bitRate) {
+ protected void setVideoEncodingBitRate(int bitRate) {
videoBitRate = bitRate;
}
@Implementation
- public void setVideoFrameRate(int rate) {
+ protected void setVideoFrameRate(int rate) {
videoFrameRate = rate;
state = STATE_DATA_SOURCE_CONFIGURED;
}
@Implementation
- public void setVideoSize(int width, int height) {
+ protected void setVideoSize(int width, int height) {
videoWidth = width;
videoHeight = height;
state = STATE_DATA_SOURCE_CONFIGURED;
}
@Implementation
- public void setVideoSource(int video_source) {
+ protected void setVideoSource(int video_source) {
videoSource = video_source;
state = STATE_INITIALIZED;
}
@Implementation
- public void prepare() {
+ protected void prepare() {
state = STATE_PREPARED;
}
@Implementation
- public void start() {
+ protected void start() {
state = STATE_RECORDING;
}
@Implementation
- public void stop() {
+ protected void stop() {
state = STATE_INITIAL;
}
@Implementation
- public void reset() {
+ protected void reset() {
state = STATE_INITIAL;
}
@Implementation
- public void release() {
+ protected void release() {
state = STATE_RELEASED;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaStore.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaStore.java
index cc1521ade..d9609b36e 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaStore.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaStore.java
@@ -18,7 +18,7 @@ public class ShadowMediaStore {
public static class ShadowMedia {
@Implementation
- public static Bitmap getBitmap(ContentResolver cr, Uri url) {
+ protected static Bitmap getBitmap(ContentResolver cr, Uri url) {
return ShadowBitmapFactory.create(url.toString());
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMemoryMappedFile.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMemoryMappedFile.java
index f9095b435..5af527198 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMemoryMappedFile.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMemoryMappedFile.java
@@ -81,6 +81,7 @@ public class ShadowMemoryMappedFile {
}
@Implementation
+ @SuppressWarnings("robolectric.ShadowReturnTypeMismatch")
public int size() {
return bytes.length;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessage.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessage.java
index cb36cb219..8d6846728 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessage.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessage.java
@@ -56,12 +56,11 @@ public class ShadowMessage {
}
/**
- * Hook to unscheduled the callback when the message is recycled.
- * Invokes {@link #unschedule()} and then calls through to
- * {@link Message#recycle()} on the real object.
+ * Hook to unscheduled the callback when the message is recycled. Invokes {@link #unschedule()}
+ * and then calls through to {@link Message#recycle()} on the real object.
*/
@Implementation(maxSdk = KITKAT_WATCH)
- public void recycle() {
+ protected void recycle() {
unschedule();
directlyOn(realMessage, Message.class, "recycle");
}
@@ -85,18 +84,18 @@ public class ShadowMessage {
}
/**
- * Convenience method to provide access to the private {@code Message.isInUse()}
- * method. Note that the definition of "in use" changed with API 21:
+ * Convenience method to provide access to the private {@code Message.isInUse()} method. Note that
+ * the definition of "in use" changed with API 21:
*
- * In API 19, a message was only considered "in use" during its dispatch. In API 21, the
- * message is considered "in use" from the time it is enqueued until the time that
- * it is freshly obtained via a call to {@link Message#obtain()}. This means that
- * in API 21 messages that are in the recycled pool will still be marked as "in use".
+ * <p>In API 19, a message was only considered "in use" during its dispatch. In API 21, the
+ * message is considered "in use" from the time it is enqueued until the time that it is freshly
+ * obtained via a call to {@link Message#obtain()}. This means that in API 21 messages that are in
+ * the recycled pool will still be marked as "in use".
*
* @return {@code true} if the message is currently "in use", {@code false} otherwise.
*/
@Implementation
- public boolean isInUse() {
+ protected boolean isInUse() {
return directlyOn(realMessage, Message.class, "isInUse");
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessageQueue.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessageQueue.java
index 57b311277..5ad4e32be 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessageQueue.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessageQueue.java
@@ -44,6 +44,7 @@ public class ShadowMessageQueue {
// rather than automatic.
@HiddenApi
@Implementation
+ @SuppressWarnings("robolectric.ShadowReturnTypeMismatch")
public static Number nativeInit() {
return 1;
}
@@ -55,8 +56,7 @@ public class ShadowMessageQueue {
}
@Implementation(minSdk = LOLLIPOP)
- public static void nativeDestroy(long ptr) {
- }
+ protected static void nativeDestroy(long ptr) {}
@HiddenApi
@Implementation(minSdk = KITKAT, maxSdk = KITKAT_WATCH)
@@ -65,7 +65,7 @@ public class ShadowMessageQueue {
}
@Implementation(minSdk = LOLLIPOP, maxSdk = LOLLIPOP_MR1)
- public static boolean nativeIsIdling(long ptr) {
+ protected static boolean nativeIsIdling(long ptr) {
return false;
}
@@ -93,7 +93,7 @@ public class ShadowMessageQueue {
@Implementation
@SuppressWarnings("SynchronizeOnNonFinalField")
- public boolean enqueueMessage(final Message msg, long when) {
+ protected boolean enqueueMessage(final Message msg, long when) {
final boolean retval = directlyOn(realQueue, MessageQueue.class, "enqueueMessage", from(Message.class, msg), from(long.class, when));
if (retval) {
final Runnable callback = new Runnable() {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessenger.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessenger.java
index fb89fab54..0594f0786 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessenger.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMessenger.java
@@ -29,28 +29,28 @@ public class ShadowMessenger {
private Handler handler;
@Implementation
- public void __constructor__(Handler handler) {
+ protected void __constructor__(Handler handler) {
this.handler = handler;
Object target = ReflectionHelpers.callInstanceMethod(handler, "getIMessenger");
ReflectionHelpers.setField(messenger, "mTarget", target);
}
@Implementation
- public void __constructor__(IBinder target) {
+ protected void __constructor__(IBinder target) {
if (target != null && target instanceof FakeBinder) {
handler = ((FakeBinder) target).handler;
}
}
@Implementation
- public void send(Message message) throws RemoteException {
+ protected void send(Message message) throws RemoteException {
lastMessageSent = message;
message.setTarget(handler);
message.sendToTarget();
}
@Implementation
- public IBinder getBinder() {
+ protected IBinder getBinder() {
return new FakeBinder(handler);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMimeTypeMap.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMimeTypeMap.java
index c8a4a3234..d1e9f3d6c 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMimeTypeMap.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMimeTypeMap.java
@@ -16,7 +16,7 @@ public class ShadowMimeTypeMap {
private static final Object singletonLock = new Object();
@Implementation
- public static MimeTypeMap getSingleton() {
+ protected static MimeTypeMap getSingleton() {
if (singleton == null) {
synchronized (singletonLock) {
if (singleton == null) {
@@ -37,7 +37,7 @@ public class ShadowMimeTypeMap {
}
@Implementation
- public String getMimeTypeFromExtension(String extension) {
+ protected String getMimeTypeFromExtension(String extension) {
if (extensionToMimeTypeMap.containsKey(extension))
return extensionToMimeTypeMap.get(extension);
@@ -45,7 +45,7 @@ public class ShadowMimeTypeMap {
}
@Implementation
- public String getExtensionFromMimeType(String mimeType) {
+ protected String getExtensionFromMimeType(String mimeType) {
if (mimeTypeToExtensionMap.containsKey(mimeType))
return mimeTypeToExtensionMap.get(mimeType);
@@ -63,12 +63,12 @@ public class ShadowMimeTypeMap {
}
@Implementation
- public boolean hasExtension(String extension) {
+ protected boolean hasExtension(String extension) {
return extensionToMimeTypeMap.containsKey(extension);
}
@Implementation
- public boolean hasMimeType(String mimeType) {
+ protected boolean hasMimeType(String mimeType) {
return mimeTypeToExtensionMap.containsKey(mimeType);
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMotionEvent.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMotionEvent.java
index 9a63f1cc8..c422b70e4 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMotionEvent.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMotionEvent.java
@@ -646,12 +646,14 @@ public class ShadowMotionEvent {
@Implementation(maxSdk = KITKAT_WATCH)
@HiddenApi
- protected static void nativeSetSource(int nativePtr, int source) {
+ protected static int nativeSetSource(int nativePtr, int source) {
nativeSetSource((long) nativePtr, source);
+ return 0;
}
@Implementation(minSdk = LOLLIPOP)
@HiddenApi
+ @SuppressWarnings("robolectric.ShadowReturnTypeMismatch")
protected static void nativeSetSource(long nativePtr, int source) {
NativeInput.MotionEvent event = getNativeMotionEvent(nativePtr);
event.setSource(source);
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNetwork.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNetwork.java
index 71899b271..8981bca19 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNetwork.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNetwork.java
@@ -27,7 +27,7 @@ public class ShadowNetwork {
}
@Implementation
- public void __constructor__(int netId) {
+ protected void __constructor__(int netId) {
this.netId = netId;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNetworkInfo.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNetworkInfo.java
index 29c542164..19d26f252 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNetworkInfo.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNetworkInfo.java
@@ -12,9 +12,9 @@ public class ShadowNetworkInfo {
private int connectionType;
private int connectionSubType;
private NetworkInfo.DetailedState detailedState;
-
+
@Implementation
- public static void __staticInitializer__() {}
+ protected static void __staticInitializer__() {}
/**
* @deprecated use {@link #newInstance(NetworkInfo.DetailedState, int, int, boolean,
@@ -53,37 +53,37 @@ public class ShadowNetworkInfo {
}
@Implementation
- public boolean isConnected() {
+ protected boolean isConnected() {
return state == NetworkInfo.State.CONNECTED;
}
@Implementation
- public boolean isConnectedOrConnecting() {
+ protected boolean isConnectedOrConnecting() {
return isConnected() || state == NetworkInfo.State.CONNECTING;
}
@Implementation
- public NetworkInfo.State getState() {
+ protected NetworkInfo.State getState() {
return state;
}
@Implementation
- public NetworkInfo.DetailedState getDetailedState() {
+ protected NetworkInfo.DetailedState getDetailedState() {
return detailedState;
}
@Implementation
- public int getType(){
+ protected int getType() {
return connectionType;
}
@Implementation
- public int getSubtype() {
+ protected int getSubtype() {
return connectionSubType;
}
@Implementation
- public boolean isAvailable() {
+ protected boolean isAvailable() {
return isAvailable;
}
@@ -124,7 +124,7 @@ public class ShadowNetworkInfo {
*
* @param connectionType the value that {@link #getType()} will return.
*/
- public void setConnectionType(int connectionType){
+ public void setConnectionType(int connectionType) {
this.connectionType = connectionType;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNfcAdapter.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNfcAdapter.java
index 1ddd8073c..b39cac8bc 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNfcAdapter.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNfcAdapter.java
@@ -28,7 +28,7 @@ public class ShadowNfcAdapter {
private NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback;
@Implementation
- public static NfcAdapter getNfcAdapter(Context context) {
+ protected static NfcAdapter getNfcAdapter(Context context) {
if (!hardwareExists) {
return null;
}
@@ -36,7 +36,8 @@ public class ShadowNfcAdapter {
}
@Implementation
- public void enableForegroundDispatch(Activity activity, PendingIntent intent, IntentFilter[] filters, String[][] techLists) {
+ protected void enableForegroundDispatch(
+ Activity activity, PendingIntent intent, IntentFilter[] filters, String[][] techLists) {
this.enabledActivity = activity;
this.intent = intent;
this.filters = filters;
@@ -44,7 +45,7 @@ public class ShadowNfcAdapter {
}
@Implementation
- public void disableForegroundDispatch(Activity activity) {
+ protected void disableForegroundDispatch(Activity activity) {
disabledActivity = activity;
}
@@ -68,7 +69,8 @@ public class ShadowNfcAdapter {
}
@Implementation
- public void setNdefPushMessageCallback(NfcAdapter.CreateNdefMessageCallback callback, Activity activity, Activity... activities) {
+ protected void setNdefPushMessageCallback(
+ NfcAdapter.CreateNdefMessageCallback callback, Activity activity, Activity... activities) {
this.ndefPushMessageCallback = callback;
}
@@ -79,7 +81,7 @@ public class ShadowNfcAdapter {
* #getOnNdefPushCompleteCallback}.
*/
@Implementation
- public void setOnNdefPushCompleteCallback(
+ protected void setOnNdefPushCompleteCallback(
NfcAdapter.OnNdefPushCompleteCallback callback, Activity activity, Activity... activities) {
if (activity == null) {
throw new NullPointerException("activity cannot be null");
@@ -93,7 +95,7 @@ public class ShadowNfcAdapter {
}
@Implementation
- public boolean isEnabled() {
+ protected boolean isEnabled() {
return enabled;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNinePatch.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNinePatch.java
index 52257031e..917586094 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNinePatch.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNinePatch.java
@@ -7,7 +7,7 @@ import org.robolectric.annotation.Implements;
@Implements(NinePatch.class)
public class ShadowNinePatch {
@Implementation
- public static boolean isNinePatchChunk(byte[] chunk) {
+ protected static boolean isNinePatchChunk(byte[] chunk) {
return chunk != null;
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNotificationManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNotificationManager.java
index ee8c708a2..7be1c644e 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNotificationManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNotificationManager.java
@@ -38,22 +38,22 @@ public class ShadowNotificationManager {
private Policy notificationPolicy;
@Implementation
- public void notify(int id, Notification notification) {
+ protected void notify(int id, Notification notification) {
notify(null, id, notification);
}
@Implementation
- public void notify(String tag, int id, Notification notification) {
+ protected void notify(String tag, int id, Notification notification) {
notifications.put(new Key(tag, id), notification);
}
@Implementation
- public void cancel(int id) {
+ protected void cancel(int id) {
cancel(null, id);
}
@Implementation
- public void cancel(String tag, int id) {
+ protected void cancel(String tag, int id) {
Key key = new Key(tag, id);
if (notifications.containsKey(key)) {
notifications.remove(key);
@@ -61,12 +61,12 @@ public class ShadowNotificationManager {
}
@Implementation
- public void cancelAll() {
+ protected void cancelAll() {
notifications.clear();
}
@Implementation(minSdk = Build.VERSION_CODES.N)
- public boolean areNotificationsEnabled() {
+ protected boolean areNotificationsEnabled() {
return mAreNotificationsEnabled;
}
@@ -96,23 +96,23 @@ public class ShadowNotificationManager {
}
@Implementation(minSdk = Build.VERSION_CODES.O)
- public Object /*NotificationChannel*/ getNotificationChannel(String channelId) {
+ protected Object /*NotificationChannel*/ getNotificationChannel(String channelId) {
return notificationChannels.get(channelId);
}
@Implementation(minSdk = Build.VERSION_CODES.O)
- public void createNotificationChannelGroup(Object /*NotificationChannelGroup*/ group) {
+ protected void createNotificationChannelGroup(Object /*NotificationChannelGroup*/ group) {
String id = ReflectionHelpers.callInstanceMethod(group, "getId");
notificationChannelGroups.put(id, group);
}
@Implementation(minSdk = Build.VERSION_CODES.O)
- public List<Object /*NotificationChannelGroup*/> getNotificationChannelGroups() {
+ protected List<Object /*NotificationChannelGroup*/> getNotificationChannelGroups() {
return ImmutableList.copyOf(notificationChannelGroups.values());
}
@Implementation(minSdk = Build.VERSION_CODES.O)
- public void createNotificationChannel(Object /*NotificationChannel*/ channel) {
+ protected void createNotificationChannel(Object /*NotificationChannel*/ channel) {
String id = ReflectionHelpers.callInstanceMethod(channel, "getId");
// Per documentation, recreating a deleted channel should have the same settings as the old
// deleted channel. See
@@ -126,7 +126,7 @@ public class ShadowNotificationManager {
}
@Implementation(minSdk = Build.VERSION_CODES.O)
- public void createNotificationChannels(List<Object /*NotificationChannel*/> channelList) {
+ protected void createNotificationChannels(List<Object /*NotificationChannel*/> channelList) {
for (Object channel : channelList) {
createNotificationChannel(channel);
}
@@ -138,7 +138,7 @@ public class ShadowNotificationManager {
}
@Implementation(minSdk = Build.VERSION_CODES.O)
- public void deleteNotificationChannel(String channelId) {
+ protected void deleteNotificationChannel(String channelId) {
if (getNotificationChannel(channelId) != null) {
Object /*NotificationChannel*/ channel = notificationChannels.remove(channelId);
deletedNotificationChannels.put(channelId, channel);
@@ -151,7 +151,7 @@ public class ShadowNotificationManager {
* notification channel groups nor to notification channels.
*/
@Implementation(minSdk = Build.VERSION_CODES.O)
- public void deleteNotificationChannelGroup(String channelGroupId) {
+ protected void deleteNotificationChannelGroup(String channelGroupId) {
if (getNotificationChannelGroup(channelGroupId) != null) {
// Deleting a channel group also deleted all associated channels. See
// https://developer.android.com/reference/android/app/NotificationManager.html#deleteNotificationChannelGroup%28java.lang.String%29
@@ -182,7 +182,7 @@ public class ShadowNotificationManager {
* @see NotificationManager#getCurrentInterruptionFilter()
*/
@Implementation(minSdk = M)
- public final void setInterruptionFilter(int interruptionFilter) {
+ protected final void setInterruptionFilter(int interruptionFilter) {
currentInteruptionFilter = interruptionFilter;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNsdManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNsdManager.java
index 18c2f8ccc..fb6823194 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNsdManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNsdManager.java
@@ -4,7 +4,6 @@ import android.net.nsd.NsdManager;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
-/** Shadow for {@link android.net.nsd.NsdManager} */
@Implements(NsdManager.class)
public class ShadowNsdManager {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNumberPicker.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNumberPicker.java
index 22cd77904..031308537 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNumberPicker.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNumberPicker.java
@@ -18,57 +18,57 @@ public class ShadowNumberPicker extends ShadowLinearLayout {
private NumberPicker.OnValueChangeListener onValueChangeListener;
@Implementation
- public void setValue(int value) {
+ protected void setValue(int value) {
this.value = value;
}
@Implementation
- public int getValue() {
+ protected int getValue() {
return value;
}
@Implementation
- public void setDisplayedValues(String[] displayedValues) {
+ protected void setDisplayedValues(String[] displayedValues) {
this.displayedValues = displayedValues;
}
@Implementation
- public String[] getDisplayedValues() {
+ protected String[] getDisplayedValues() {
return displayedValues;
}
@Implementation
- public void setMinValue(int minValue) {
+ protected void setMinValue(int minValue) {
this.minValue = minValue;
}
@Implementation
- public void setMaxValue(int maxValue) {
+ protected void setMaxValue(int maxValue) {
this.maxValue = maxValue;
}
@Implementation
- public int getMinValue() {
+ protected int getMinValue() {
return this.minValue;
}
@Implementation
- public int getMaxValue() {
+ protected int getMaxValue() {
return this.maxValue;
}
@Implementation
- public void setWrapSelectorWheel(boolean wrapSelectorWheel) {
+ protected void setWrapSelectorWheel(boolean wrapSelectorWheel) {
this.wrapSelectorWheel = wrapSelectorWheel;
}
@Implementation
- public boolean getWrapSelectorWheel() {
+ protected boolean getWrapSelectorWheel() {
return wrapSelectorWheel;
}
@Implementation
- public void setOnValueChangedListener(NumberPicker.OnValueChangeListener listener) {
+ protected void setOnValueChangedListener(NumberPicker.OnValueChangeListener listener) {
directlyOn(realNumberPicker, NumberPicker.class).setOnValueChangedListener(listener);
this.onValueChangeListener = listener;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOpenGLMatrix.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOpenGLMatrix.java
index 6bec3f8ff..2f91ba9c2 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOpenGLMatrix.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOpenGLMatrix.java
@@ -8,30 +8,26 @@ import org.robolectric.annotation.Implements;
public class ShadowOpenGLMatrix {
/**
- * Multiplies two 4x4 matrices together and stores the result in a third 4x4
- * matrix. In matrix notation: result = lhs x rhs. Due to the way
- * matrix multiplication works, the result matrix will have the same
- * effect as first multiplying by the rhs matrix, then multiplying by
- * the lhs matrix. This is the opposite of what you might expect.
+ * Multiplies two 4x4 matrices together and stores the result in a third 4x4 matrix. In matrix
+ * notation: result = lhs x rhs. Due to the way matrix multiplication works, the result matrix
+ * will have the same effect as first multiplying by the rhs matrix, then multiplying by the lhs
+ * matrix. This is the opposite of what you might expect.
*
- * The same float array may be passed for result, lhs, and/or rhs. However,
- * the result element values are undefined if the result elements overlap
- * either the lhs or rhs elements.
+ * <p>The same float array may be passed for result, lhs, and/or rhs. However, the result element
+ * values are undefined if the result elements overlap either the lhs or rhs elements.
*
- * @param result The float array that holds the result.
- * @param resultOffset The offset into the result array where the result is
- * stored.
- * @param lhs The float array that holds the left-hand-side matrix.
- * @param lhsOffset The offset into the lhs array where the lhs is stored
- * @param rhs The float array that holds the right-hand-side matrix.
- * @param rhsOffset The offset into the rhs array where the rhs is stored.
- * @throws IllegalArgumentException if result, lhs, or rhs are null, or if
- * resultOffset + 16 > result.length or lhsOffset + 16 > lhs.length or
- * rhsOffset + 16 > rhs.length.
+ * @param result The float array that holds the result.
+ * @param resultOffset The offset into the result array where the result is stored.
+ * @param lhs The float array that holds the left-hand-side matrix.
+ * @param lhsOffset The offset into the lhs array where the lhs is stored
+ * @param rhs The float array that holds the right-hand-side matrix.
+ * @param rhsOffset The offset into the rhs array where the rhs is stored.
+ * @throws IllegalArgumentException if result, lhs, or rhs are null, or if resultOffset + 16 >
+ * result.length or lhsOffset + 16 > lhs.length or rhsOffset + 16 > rhs.length.
*/
@Implementation
- public static void multiplyMM(float[] result, int resultOffset,
- float[] lhs, int lhsOffset, float[] rhs, int rhsOffset) {
+ protected static void multiplyMM(
+ float[] result, int resultOffset, float[] lhs, int lhsOffset, float[] rhs, int rhsOffset) {
if (result == null) {
throw new IllegalArgumentException("result == null");
}
@@ -71,30 +67,31 @@ public class ShadowOpenGLMatrix {
}
/**
- * Multiplies a 4 element vector by a 4x4 matrix and stores the result in a
- * 4-element column vector. In matrix notation: result = lhs x rhs
+ * Multiplies a 4 element vector by a 4x4 matrix and stores the result in a 4-element column
+ * vector. In matrix notation: result = lhs x rhs
*
- * The same float array may be passed for resultVec, lhsMat, and/or rhsVec.
- * However, the resultVec element values are undefined if the resultVec
- * elements overlap either the lhsMat or rhsVec elements.
+ * <p>The same float array may be passed for resultVec, lhsMat, and/or rhsVec. However, the
+ * resultVec element values are undefined if the resultVec elements overlap either the lhsMat or
+ * rhsVec elements.
*
- * @param resultVec The float array that holds the result vector.
- * @param resultVecOffset The offset into the result array where the result
- * vector is stored.
- * @param lhsMat The float array that holds the left-hand-side matrix.
- * @param lhsMatOffset The offset into the lhs array where the lhs is stored
- * @param rhsVec The float array that holds the right-hand-side vector.
- * @param rhsVecOffset The offset into the rhs vector where the rhs vector
- * is stored.
- * @throws IllegalArgumentException if resultVec, lhsMat,
- * or rhsVec are null, or if resultVecOffset + 4 > resultVec.length
- * or lhsMatOffset + 16 > lhsMat.length or
- * rhsVecOffset + 4 > rhsVec.length.
+ * @param resultVec The float array that holds the result vector.
+ * @param resultVecOffset The offset into the result array where the result vector is stored.
+ * @param lhsMat The float array that holds the left-hand-side matrix.
+ * @param lhsMatOffset The offset into the lhs array where the lhs is stored
+ * @param rhsVec The float array that holds the right-hand-side vector.
+ * @param rhsVecOffset The offset into the rhs vector where the rhs vector is stored.
+ * @throws IllegalArgumentException if resultVec, lhsMat, or rhsVec are null, or if
+ * resultVecOffset + 4 > resultVec.length or lhsMatOffset + 16 > lhsMat.length or rhsVecOffset
+ * + 4 > rhsVec.length.
*/
@Implementation
- public static void multiplyMV(float[] resultVec,
- int resultVecOffset, float[] lhsMat, int lhsMatOffset,
- float[] rhsVec, int rhsVecOffset) {
+ protected static void multiplyMV(
+ float[] resultVec,
+ int resultVecOffset,
+ float[] lhsMat,
+ int lhsMatOffset,
+ float[] rhsVec,
+ int rhsVecOffset) {
if (resultVec == null) {
throw new IllegalArgumentException("resultVec == null");
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOutline.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOutline.java
index 25ede37c6..d09466817 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOutline.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOutline.java
@@ -11,6 +11,5 @@ import org.robolectric.annotation.Implements;
public class ShadowOutline {
@Implementation
- public void setConvexPath(Path convexPath) {
- }
+ protected void setConvexPath(Path convexPath) {}
} \ No newline at end of file
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOverScroller.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOverScroller.java
index 9a72a4d09..00d01c1b8 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOverScroller.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowOverScroller.java
@@ -18,44 +18,44 @@ public class ShadowOverScroller {
private boolean started;
@Implementation
- public int getStartX() {
+ protected int getStartX() {
return startX;
}
@Implementation
- public int getStartY() {
+ protected int getStartY() {
return startY;
}
@Implementation
- public int getCurrX() {
+ protected int getCurrX() {
long dt = deltaTime();
return dt >= duration ? finalX : startX + (int) ((deltaX() * dt) / duration);
}
@Implementation
- public int getCurrY() {
+ protected int getCurrY() {
long dt = deltaTime();
return dt >= duration ? finalY : startY + (int) ((deltaY() * dt) / duration);
}
@Implementation
- public int getFinalX() {
+ protected int getFinalX() {
return finalX;
}
@Implementation
- public int getFinalY() {
+ protected int getFinalY() {
return finalY;
}
@Implementation
- public int getDuration() {
+ protected int getDuration() {
return (int) duration;
}
@Implementation
- public void startScroll(int startX, int startY, int dx, int dy, int duration) {
+ protected void startScroll(int startX, int startY, int dx, int dy, int duration) {
this.startX = startX;
this.startY = startY;
finalX = startX + dx;
@@ -73,12 +73,12 @@ public class ShadowOverScroller {
}
@Implementation
- public void abortAnimation() {
+ protected void abortAnimation() {
duration = deltaTime() - 1;
}
@Implementation
- public void forceFinished(boolean finished) {
+ protected void forceFinished(boolean finished) {
if (!finished) {
throw new RuntimeException("Not implemented.");
}
@@ -89,7 +89,7 @@ public class ShadowOverScroller {
}
@Implementation
- public boolean computeScrollOffset() {
+ protected boolean computeScrollOffset() {
if (!started) {
return false;
}
@@ -98,17 +98,17 @@ public class ShadowOverScroller {
}
@Implementation
- public boolean isFinished() {
+ protected boolean isFinished() {
return deltaTime() > duration;
}
@Implementation
- public int timePassed() {
+ protected int timePassed() {
return (int) deltaTime();
}
@Implementation
- public boolean isScrollingInDirection(float xvel, float yvel) {
+ protected boolean isScrollingInDirection(float xvel, float yvel) {
final int dx = finalX - startX;
final int dy = finalY - startY;
return !isFinished()
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageInstaller.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageInstaller.java
index 217af64a4..ef6be55ad 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageInstaller.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageInstaller.java
@@ -38,12 +38,13 @@ public class ShadowPackageInstaller {
}
@Implementation
- public List<PackageInstaller.SessionInfo> getAllSessions() {
+ protected List<PackageInstaller.SessionInfo> getAllSessions() {
return ImmutableList.copyOf(sessionInfos.values());
}
@Implementation
- public void registerSessionCallback(@NonNull PackageInstaller.SessionCallback callback, @NonNull Handler handler) {
+ protected void registerSessionCallback(
+ @NonNull PackageInstaller.SessionCallback callback, @NonNull Handler handler) {
CallbackInfo callbackInfo = new CallbackInfo();
callbackInfo.callback = callback;
callbackInfo.handler = handler;
@@ -52,12 +53,12 @@ public class ShadowPackageInstaller {
@Implementation
@Nullable
- public PackageInstaller.SessionInfo getSessionInfo(int sessionId) {
+ protected PackageInstaller.SessionInfo getSessionInfo(int sessionId) {
return sessionInfos.get(sessionId);
}
@Implementation
- public int createSession(@NonNull PackageInstaller.SessionParams params) throws IOException {
+ protected int createSession(@NonNull PackageInstaller.SessionParams params) throws IOException {
final PackageInstaller.SessionInfo sessionInfo = new PackageInstaller.SessionInfo();
sessionInfo.sessionId = nextSessionId++;
sessionInfo.active = true;
@@ -77,7 +78,7 @@ public class ShadowPackageInstaller {
}
@Implementation
- public void abandonSession(int sessionId) {
+ protected void abandonSession(int sessionId) {
sessionInfos.remove(sessionId);
sessions.remove(sessionId);
@@ -93,7 +94,7 @@ public class ShadowPackageInstaller {
@Implementation
@NonNull
- public PackageInstaller.Session openSession(int sessionId) throws IOException {
+ protected PackageInstaller.Session openSession(int sessionId) throws IOException {
if (!sessionInfos.containsKey(sessionId)) {
throw new SecurityException("Invalid session Id: " + sessionId);
}
@@ -161,10 +162,12 @@ public class ShadowPackageInstaller {
private ShadowPackageInstaller shadowPackageInstaller;
@Implementation(maxSdk = KITKAT_WATCH)
- public void __constructor__() {}
+ protected void __constructor__() {}
@Implementation
- public @NonNull OutputStream openWrite(@NonNull String name, long offsetBytes, long lengthBytes) throws IOException {
+ @NonNull
+ protected OutputStream openWrite(@NonNull String name, long offsetBytes, long lengthBytes)
+ throws IOException {
outputStream = new OutputStream() {
@Override
public void write(int aByte) throws IOException {
@@ -181,12 +184,10 @@ public class ShadowPackageInstaller {
}
@Implementation
- public void fsync(@NonNull OutputStream out) throws IOException {
-
- }
+ protected void fsync(@NonNull OutputStream out) throws IOException {}
@Implementation
- public void commit(@NonNull IntentSender statusReceiver) {
+ protected void commit(@NonNull IntentSender statusReceiver) {
this.statusReceiver = statusReceiver;
if (outputStreamOpen) {
throw new SecurityException("OutputStream still open");
@@ -196,12 +197,10 @@ public class ShadowPackageInstaller {
}
@Implementation
- public void close() {
-
- }
+ protected void close() {}
@Implementation
- public void abandon() {
+ protected void abandon() {
shadowPackageInstaller.abandonSession(sessionId);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageManager.java
index 7b8c458bd..b436df89c 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageManager.java
@@ -198,12 +198,10 @@ public class ShadowPackageManager {
static final Map<String, PackageSetting> packageSettings = new HashMap<>();
-
// From com.android.server.pm.PackageManagerService.compareSignatures().
static int compareSignature(Signature[] signatures1, Signature[] signatures2) {
if (signatures1 == null) {
- return (signatures2 == null) ? SIGNATURE_NEITHER_SIGNED
- : SIGNATURE_FIRST_NOT_SIGNED;
+ return (signatures2 == null) ? SIGNATURE_NEITHER_SIGNED : SIGNATURE_FIRST_NOT_SIGNED;
}
if (signatures2 == null) {
return SIGNATURE_SECOND_NOT_SIGNED;
@@ -248,16 +246,36 @@ public class ShadowPackageManager {
applicationInfo.publicSourceDir = applicationInfo.sourceDir;
if (RuntimeEnvironment.getApiLevel() >= N) {
- applicationInfo.credentialProtectedDataDir = tempDirectory.createIfNotExists("userDataDir").toAbsolutePath().toString();
- applicationInfo.deviceProtectedDataDir = tempDirectory.createIfNotExists("deviceDataDir").toAbsolutePath().toString();
+ applicationInfo.credentialProtectedDataDir =
+ tempDirectory.createIfNotExists("userDataDir").toAbsolutePath().toString();
+ applicationInfo.deviceProtectedDataDir =
+ tempDirectory.createIfNotExists("deviceDataDir").toAbsolutePath().toString();
+ }
+ }
+
+ /**
+ * Sets extra resolve infos for an intent.
+ *
+ * <p>Those entries are added to whatever might be in the manifest already.
+ */
+ public void setResolveInfosForIntent(Intent intent, List<ResolveInfo> info) {
+ resolveInfoForIntent.remove(intent);
+ for (ResolveInfo resolveInfo : info) {
+ addResolveInfoForIntent(intent, resolveInfo);
}
}
+ /**
+ * @deprecated please use {@link #setResolveInfosForIntent} or {@link
+ * #addResolveInfoForIntent(Intent, ResolveInfo)} instead.
+ */
+ @Deprecated
public void addResolveInfoForIntent(Intent intent, List<ResolveInfo> info) {
- resolveInfoForIntent.put(intent, info);
+ setResolveInfosForIntent(intent, info);
}
public void addResolveInfoForIntent(Intent intent, ResolveInfo info) {
+ Preconditions.checkNotNull(info);
List<ResolveInfo> infoList = resolveInfoForIntent.get(intent);
if (infoList == null) {
infoList = new ArrayList<>();
@@ -313,7 +331,8 @@ public class ShadowPackageManager {
}
/**
- * Return the flags set in call to {@link android.app.ApplicationPackageManager#setComponentEnabledSetting(ComponentName, int, int)}.
+ * Return the flags set in call to {@link
+ * android.app.ApplicationPackageManager#setComponentEnabledSetting(ComponentName, int, int)}.
*
* @param componentName The component name.
* @return The flags.
@@ -340,9 +359,8 @@ public class ShadowPackageManager {
/**
* Registers ("installs") a package with the PackageManager.
*
- * <p>
- * In order to create PackageInfo objects in a valid state please use
- * {@link androidx.test.core.content.pm.PackageInfoBuilder}.
+ * <p>In order to create PackageInfo objects in a valid state please use {@link
+ * androidx.test.core.content.pm.PackageInfoBuilder}.
*/
public void addPackage(PackageInfo packageInfo) {
PackageStats packageStats = new PackageStats(packageInfo.packageName);
@@ -357,7 +375,8 @@ public class ShadowPackageManager {
packageSettings.put(packageInfo.packageName, new PackageSetting());
- applicationEnabledSettingMap.put(packageInfo.packageName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
+ applicationEnabledSettingMap.put(
+ packageInfo.packageName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
if (packageInfo.applicationInfo != null) {
namesForUid.put(packageInfo.applicationInfo.uid, packageInfo.packageName);
}
@@ -383,9 +402,11 @@ public class ShadowPackageManager {
/**
* Allows overriding or adding permission-group elements. These would be otherwise specified by
- * either (the system)[https://developer.android.com/guide/topics/permissions/requesting.html#perm-groups]
- * or by (the app itself)[https://developer.android.com/guide/topics/manifest/permission-group-element.html],
- * as part of its manifest
+ * either (the
+ * system)[https://developer.android.com/guide/topics/permissions/requesting.html#perm-groups] or
+ * by (the app
+ * itself)[https://developer.android.com/guide/topics/manifest/permission-group-element.html], as
+ * part of its manifest
*
* <p>{@link android.content.pm.PackageParser.PermissionGroup}s added through this method have
* precedence over those specified with the same name by one of the aforementioned methods.
@@ -402,7 +423,6 @@ public class ShadowPackageManager {
packageInfos.remove(packageName);
packageSettings.remove(packageName);
-
}
public void setSystemFeature(String name, boolean supported) {
@@ -527,7 +547,8 @@ public class ShadowPackageManager {
protected void freeStorage(long freeStorageSize, IntentSender pi) {}
/**
- * Runs the callbacks pending from calls to {@link PackageManager#deletePackage(String, IPackageDeleteObserver, int)}
+ * Runs the callbacks pending from calls to {@link PackageManager#deletePackage(String,
+ * IPackageDeleteObserver, int)}
*/
public void doPendingUninstallCallbacks() {
boolean hasDeletePackagesPermission = false;
@@ -565,8 +586,9 @@ public class ShadowPackageManager {
}
/**
- * Returns package names successfully deleted with {@link PackageManager#deletePackage(String, IPackageDeleteObserver, int)}
- * Note that like real {@link PackageManager} the calling context must have {@link android.Manifest.permission#DELETE_PACKAGES} permission set.
+ * Returns package names successfully deleted with {@link PackageManager#deletePackage(String,
+ * IPackageDeleteObserver, int)} Note that like real {@link PackageManager} the calling context
+ * must have {@link android.Manifest.permission#DELETE_PACKAGES} permission set.
*/
public Set<String> getDeletedPackages() {
return deletedPackages;
@@ -583,6 +605,7 @@ public class ShadowPackageManager {
/**
* Internal use only.
+ *
* @param appPackage
*/
public void addPackageInternal(Package appPackage) {
@@ -659,8 +682,10 @@ public class ShadowPackageManager {
}
packageInfo.applicationInfo.uid = Process.myUid();
- packageInfo.applicationInfo.dataDir = RuntimeEnvironment.getTempDirectory()
- .createIfNotExists(packageInfo.packageName + "-dataDir").toString();
+ packageInfo.applicationInfo.dataDir =
+ RuntimeEnvironment.getTempDirectory()
+ .createIfNotExists(packageInfo.packageName + "-dataDir")
+ .toString();
addPackage(packageInfo);
}
@@ -974,8 +999,6 @@ public class ShadowPackageManager {
hiddenPackages.clear();
sequenceNumberChangedPackagesMap.clear();
-
packageSettings.clear();
-
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageParser.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageParser.java
index e71ab5a20..6777956fd 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageParser.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPackageParser.java
@@ -14,9 +14,6 @@ import org.robolectric.res.FsFile;
import org.robolectric.shadows.ShadowLog.LogItem;
import org.robolectric.util.ReflectionHelpers;
-/**
- * Shadow for {@link PackageParser}
- */
@Implements(value = PackageParser.class, isInAndroidSdk = false)
public class ShadowPackageParser {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java
index afdbff373..479d02aeb 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java
@@ -40,7 +40,7 @@ public class ShadowPaint {
private Paint.Align textAlign = Paint.Align.LEFT;
@Implementation
- public void __constructor__(Paint otherPaint) {
+ protected void __constructor__(Paint otherPaint) {
ShadowPaint otherShadowPaint = Shadow.extract(otherPaint);
this.color = otherShadowPaint.color;
this.style = otherShadowPaint.style;
@@ -63,94 +63,93 @@ public class ShadowPaint {
}
@Implementation(minSdk = N)
- public static long nInit() {
+ protected static long nInit() {
return 1;
}
@Implementation
- public int getFlags() {
+ protected int getFlags() {
return flags;
}
@Implementation
- public void setFlags(int flags) {
+ protected void setFlags(int flags) {
this.flags = flags;
}
@Implementation
- public Shader setShader(Shader shader) {
+ protected Shader setShader(Shader shader) {
this.shader = shader;
return shader;
}
@Implementation
- public int getAlpha() {
+ protected int getAlpha() {
return alpha;
}
@Implementation
- public void setAlpha(int alpha) {
+ protected void setAlpha(int alpha) {
this.alpha = alpha;
}
-
@Implementation
- public Shader getShader() {
+ protected Shader getShader() {
return shader;
}
@Implementation
- public void setColor(int color) {
+ protected void setColor(int color) {
this.color = color;
}
@Implementation
- public int getColor() {
+ protected int getColor() {
return color;
}
@Implementation
- public void setStyle(Paint.Style style) {
+ protected void setStyle(Paint.Style style) {
this.style = style;
}
@Implementation
- public Paint.Style getStyle() {
+ protected Paint.Style getStyle() {
return style;
}
@Implementation
- public void setStrokeCap(Paint.Cap cap) {
+ protected void setStrokeCap(Paint.Cap cap) {
this.cap = cap;
}
@Implementation
- public Paint.Cap getStrokeCap() {
+ protected Paint.Cap getStrokeCap() {
return cap;
}
@Implementation
- public void setStrokeJoin(Paint.Join join) {
+ protected void setStrokeJoin(Paint.Join join) {
this.join = join;
}
@Implementation
- public Paint.Join getStrokeJoin() {
+ protected Paint.Join getStrokeJoin() {
return join;
}
@Implementation
- public void setStrokeWidth(float width) {
+ protected void setStrokeWidth(float width) {
this.width = width;
}
@Implementation
- public float getStrokeWidth() {
+ protected float getStrokeWidth() {
return width;
}
@Implementation
- public void setShadowLayer(float radius, float dx, float dy, int color) {
+ protected void setShadowLayer(float radius, float dx, float dy, int color) {
shadowRadius = radius;
shadowDx = dx;
shadowDy = dy;
@@ -158,33 +157,33 @@ public class ShadowPaint {
}
@Implementation
- public Typeface getTypeface() {
+ protected Typeface getTypeface() {
return typeface;
}
@Implementation
- public Typeface setTypeface(Typeface typeface) {
+ protected Typeface setTypeface(Typeface typeface) {
this.typeface = typeface;
return typeface;
}
@Implementation
- public float getTextSize() {
+ protected float getTextSize() {
return textSize;
}
@Implementation
- public void setTextSize(float textSize) {
+ protected void setTextSize(float textSize) {
this.textSize = textSize;
}
@Implementation
- public void setTextAlign(Paint.Align align) {
+ protected void setTextAlign(Paint.Align align) {
textAlign = align;
}
@Implementation
- public Paint.Align getTextAlign() {
+ protected Paint.Align getTextAlign() {
return textAlign;
}
@@ -229,64 +228,64 @@ public class ShadowPaint {
}
@Implementation
- public ColorFilter getColorFilter() {
+ protected ColorFilter getColorFilter() {
return filter;
}
@Implementation
- public ColorFilter setColorFilter(ColorFilter filter) {
+ protected ColorFilter setColorFilter(ColorFilter filter) {
this.filter = filter;
return filter;
}
@Implementation
- public void setAntiAlias(boolean antiAlias) {
+ protected void setAntiAlias(boolean antiAlias) {
this.flags = (flags & ~Paint.ANTI_ALIAS_FLAG) | (antiAlias ? Paint.ANTI_ALIAS_FLAG : 0);
}
@Implementation
- public void setDither(boolean dither) {
+ protected void setDither(boolean dither) {
this.dither = dither;
}
@Implementation
- public final boolean isDither() {
+ protected final boolean isDither() {
return dither;
}
@Implementation
- public final boolean isAntiAlias() {
+ protected final boolean isAntiAlias() {
return (flags & Paint.ANTI_ALIAS_FLAG) == Paint.ANTI_ALIAS_FLAG;
}
@Implementation
- public PathEffect getPathEffect() {
+ protected PathEffect getPathEffect() {
return pathEffect;
}
@Implementation
- public PathEffect setPathEffect(PathEffect effect) {
+ protected PathEffect setPathEffect(PathEffect effect) {
this.pathEffect = effect;
return effect;
}
@Implementation
- public float measureText(String text) {
+ protected float measureText(String text) {
return text.length();
}
@Implementation
- public float measureText(CharSequence text, int start, int end) {
+ protected float measureText(CharSequence text, int start, int end) {
return end - start;
}
@Implementation
- public float measureText(String text, int start, int end) {
+ protected float measureText(String text, int start, int end) {
return end - start;
}
@Implementation
- public float measureText(char[] text, int index, int count) {
+ protected float measureText(char[] text, int index, int count) {
return count;
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowParcel.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowParcel.java
index 31f75773c..dcb9719b3 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowParcel.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowParcel.java
@@ -189,6 +189,7 @@ public class ShadowParcel {
}
@Implementation(minSdk = LOLLIPOP)
+ @SuppressWarnings("robolectric.ShadowReturnTypeMismatch")
protected static void nativeSetDataSize(long nativePtr, int size) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).setDataSize(size);
}
@@ -423,6 +424,7 @@ public class ShadowParcel {
}
@Implementation(minSdk = LOLLIPOP)
+ @SuppressWarnings("robolectric.ShadowReturnTypeMismatch")
protected static void nativeFreeBuffer(long nativePtr) {
NATIVE_PTR_TO_PARCEL.get(nativePtr).clear();
}
@@ -456,6 +458,7 @@ public class ShadowParcel {
}
@Implementation(minSdk = LOLLIPOP)
+ @SuppressWarnings("robolectric.ShadowReturnTypeMismatch")
protected static void nativeUnmarshall(long nativePtr, byte[] data, int offset, int length) {
NATIVE_PTR_TO_PARCEL.put(nativePtr, ByteBuffer.fromByteArray(data, offset, length));
}
@@ -467,6 +470,7 @@ public class ShadowParcel {
}
@Implementation(minSdk = LOLLIPOP)
+ @SuppressWarnings("robolectric.ShadowReturnTypeMismatch")
protected static void nativeAppendFrom(
long thisNativePtr, long otherNativePtr, int offset, int length) {
ByteBuffer thisByteBuffer = NATIVE_PTR_TO_PARCEL.get(thisNativePtr);
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowParcelFileDescriptor.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowParcelFileDescriptor.java
index ed5016673..524649458 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowParcelFileDescriptor.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowParcelFileDescriptor.java
@@ -16,6 +16,7 @@ import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.shadow.api.Shadow;
+import org.robolectric.util.ReflectionHelpers;
@Implements(ParcelFileDescriptor.class)
@SuppressLint("NewApi")
@@ -31,8 +32,8 @@ public class ShadowParcelFileDescriptor {
@Implementation
protected void __constructor__(ParcelFileDescriptor wrapped) {
- invokeConstructor(ParcelFileDescriptor.class, realObject,
- from(ParcelFileDescriptor.class, wrapped));
+ invokeConstructor(
+ ParcelFileDescriptor.class, realObject, from(ParcelFileDescriptor.class, wrapped));
if (wrapped != null) {
ShadowParcelFileDescriptor shadowParcelFileDescriptor = Shadow.extract(wrapped);
this.file = shadowParcelFileDescriptor.file;
@@ -59,9 +60,11 @@ public class ShadowParcelFileDescriptor {
return "rw";
}
switch (mode & ParcelFileDescriptor.MODE_READ_WRITE) {
- case ParcelFileDescriptor.MODE_READ_ONLY: return "r";
- case ParcelFileDescriptor.MODE_WRITE_ONLY: return "rw";
- case ParcelFileDescriptor.MODE_READ_WRITE: return "rw";
+ case ParcelFileDescriptor.MODE_READ_ONLY:
+ return "r";
+ case ParcelFileDescriptor.MODE_WRITE_ONLY:
+ case ParcelFileDescriptor.MODE_READ_WRITE:
+ return "rw";
}
// TODO: this probably should be an error that we reach here, but default to 'rw' for now
@@ -70,14 +73,16 @@ public class ShadowParcelFileDescriptor {
@Implementation
protected static ParcelFileDescriptor[] createPipe() throws IOException {
- File file = new File(RuntimeEnvironment.getTempDirectory().create(PIPE_TMP_DIR).toFile(), PIPE_FILE_NAME);
+ File file =
+ new File(
+ RuntimeEnvironment.getTempDirectory().create(PIPE_TMP_DIR).toFile(), PIPE_FILE_NAME);
if (!file.createNewFile()) {
throw new IOException("Cannot create pipe file: " + file.getAbsolutePath());
}
ParcelFileDescriptor readSide = open(file, ParcelFileDescriptor.MODE_READ_ONLY);
ParcelFileDescriptor writeSide = open(file, ParcelFileDescriptor.MODE_READ_WRITE);
file.deleteOnExit();
- return new ParcelFileDescriptor[]{readSide, writeSide};
+ return new ParcelFileDescriptor[] {readSide, writeSide};
}
@Implementation
@@ -98,14 +103,13 @@ public class ShadowParcelFileDescriptor {
}
}
- /**
- * Overrides framework to avoid call to {@link FileDescriptor#getInt() which does not exist on JVM.
- *
- * @return a fixed int (`0`)
- */
@Implementation
protected int getFd() {
- return 0;
+ try {
+ return ReflectionHelpers.getField(file.getFD(), "fd");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
@Implementation
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPath.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPath.java
index a709d8aab..e7253a28b 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPath.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPath.java
@@ -1,15 +1,32 @@
package org.robolectric.shadows;
+import static android.os.Build.VERSION_CODES.JELLY_BEAN;
+import static android.os.Build.VERSION_CODES.KITKAT;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
+import static org.robolectric.shadow.api.Shadow.extract;
import static org.robolectric.shadows.ShadowPath.Point.Type.LINE_TO;
import static org.robolectric.shadows.ShadowPath.Point.Type.MOVE_TO;
+import android.graphics.Matrix;
import android.graphics.Path;
+import android.graphics.Path.Direction;
+import android.graphics.RectF;
+import android.util.Log;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Area;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
import java.util.ArrayList;
import java.util.List;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
-import org.robolectric.shadow.api.Shadow;
+import org.robolectric.annotation.RealObject;
/**
* The shadow only supports straight-line paths.
@@ -17,51 +34,121 @@ import org.robolectric.shadow.api.Shadow;
@SuppressWarnings({"UnusedDeclaration"})
@Implements(Path.class)
public class ShadowPath {
+ private static final String TAG = ShadowPath.class.getSimpleName();
+ private static final float EPSILON = 1e-4f;
+
+ @RealObject private Path realObject;
+
private List<Point> points = new ArrayList<>();
private Point wasMovedTo;
- private String quadDescription = "";
+
+ private float mLastX = 0;
+ private float mLastY = 0;
+ private Path2D mPath = new Path2D.Double();
+ private boolean mCachedIsEmpty = true;
+ private Path.FillType mFillType = Path.FillType.WINDING;
+ protected boolean isSimplePath;
@Implementation
- public void __constructor__(Path path) {
- ShadowPath shadowPath = Shadow.extract(path);
+ protected void __constructor__(Path path) {
+ ShadowPath shadowPath = extract(path);
points = new ArrayList<>(shadowPath.getPoints());
- wasMovedTo = shadowPath.wasMovedTo;
- quadDescription = shadowPath.quadDescription;
+ }
+
+ Path2D getJavaShape() {
+ return mPath;
}
@Implementation
- public void moveTo(float x, float y) {
+ protected void moveTo(float x, float y) {
+ mPath.moveTo(mLastX = x, mLastY = y);
+
+ // Legacy recording behavior
Point p = new Point(x, y, MOVE_TO);
points.add(p);
- wasMovedTo = p;
}
@Implementation
- public void lineTo(float x, float y) {
+ protected void lineTo(float x, float y) {
+ if (!hasPoints()) {
+ mPath.moveTo(mLastX = 0, mLastY = 0);
+ }
+ mPath.lineTo(mLastX = x, mLastY = y);
+
+ // Legacy recording behavior
Point point = new Point(x, y, LINE_TO);
points.add(point);
}
@Implementation
- public void quadTo(float x1, float y1, float x2, float y2) {
- quadDescription = "Add a quadratic bezier from last point, approaching (" + x1 + "," + y1 + "), ending at (" + x2 + "," + y2 + ")";
+ protected void quadTo(float x1, float y1, float x2, float y2) {
+ isSimplePath = false;
+ if (!hasPoints()) {
+ moveTo(0, 0);
+ }
+ mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
+ }
+
+ @Implementation
+ protected void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) {
+ if (!hasPoints()) {
+ mPath.moveTo(0, 0);
+ }
+ mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
+ }
+
+ private boolean hasPoints() {
+ return !mPath.getPathIterator(null).isDone();
}
@Implementation
- public void reset() {
+ protected void reset() {
+ mPath.reset();
+ mLastX = 0;
+ mLastY = 0;
+
+ // Legacy recording behavior
points.clear();
- wasMovedTo = null;
- quadDescription = "";
}
- // TODO: This should only be used to enable interpolator resource parsing
@Implementation(minSdk = LOLLIPOP)
- public float[] approximate(float acceptableError) {
- return new float[]{0, 0, 0, 1, 1, 1};
- }
+ protected float[] approximate(float acceptableError) {
+ PathIterator iterator = mPath.getPathIterator(null, acceptableError);
+
+ float segment[] = new float[6];
+ float totalLength = 0;
+ ArrayList<Point2D.Float> points = new ArrayList<Point2D.Float>();
+ Point2D.Float previousPoint = null;
+ while (!iterator.isDone()) {
+ int type = iterator.currentSegment(segment);
+ Point2D.Float currentPoint = new Point2D.Float(segment[0], segment[1]);
+ // MoveTo shouldn't affect the length
+ if (previousPoint != null && type != PathIterator.SEG_MOVETO) {
+ totalLength += currentPoint.distance(previousPoint);
+ }
+ previousPoint = currentPoint;
+ points.add(currentPoint);
+ iterator.next();
+ }
+
+ int nPoints = points.size();
+ float[] result = new float[nPoints * 3];
+ previousPoint = null;
+ // Distance that we've covered so far. Used to calculate the fraction of the path that
+ // we've covered up to this point.
+ float walkedDistance = .0f;
+ for (int i = 0; i < nPoints; i++) {
+ Point2D.Float point = points.get(i);
+ float distance = previousPoint != null ? (float) previousPoint.distance(point) : .0f;
+ walkedDistance += distance;
+ result[i * 3] = walkedDistance / totalLength;
+ result[i * 3 + 1] = point.x;
+ result[i * 3 + 2] = point.y;
+
+ previousPoint = point;
+ }
- public String getQuadDescription() {
- return quadDescription;
+ return result;
}
/**
@@ -71,13 +158,6 @@ public class ShadowPath {
return points;
}
- /**
- * @return whether the {@link #moveTo(float, float)} method was called
- */
- public Point getWasMovedTo() {
- return wasMovedTo;
- }
-
public static class Point {
private final float x;
private final float y;
@@ -133,4 +213,400 @@ public class ShadowPath {
return type;
}
}
+
+ @Implementation
+ protected void rewind() {
+ // call out to reset since there's nothing to optimize in
+ // terms of data structs.
+ reset();
+ }
+
+ @Implementation
+ protected void set(Path src) {
+ mPath.reset();
+
+ ShadowPath shadowSrc = extract(src);
+ setFillType(shadowSrc.mFillType);
+ mPath.append(shadowSrc.mPath, false /*connect*/);
+ }
+
+ @Implementation(minSdk = KITKAT)
+ protected boolean op(Path path1, Path path2, Path.Op op) {
+ Log.w(TAG, "android.graphics.Path#op() not supported yet.");
+ return false;
+ }
+
+ @Implementation(minSdk = LOLLIPOP)
+ protected boolean isConvex() {
+ Log.w(TAG, "android.graphics.Path#isConvex() not supported yet.");
+ return true;
+ }
+
+ @Implementation
+ protected Path.FillType getFillType() {
+ return mFillType;
+ }
+
+ @Implementation
+ protected void setFillType(Path.FillType fillType) {
+ mFillType = fillType;
+ mPath.setWindingRule(getWindingRule(fillType));
+ }
+
+ /**
+ * Returns the Java2D winding rules matching a given Android {@link FillType}.
+ *
+ * @param type the android fill type
+ * @return the matching java2d winding rule.
+ */
+ private static int getWindingRule(Path.FillType type) {
+ switch (type) {
+ case WINDING:
+ case INVERSE_WINDING:
+ return GeneralPath.WIND_NON_ZERO;
+ case EVEN_ODD:
+ case INVERSE_EVEN_ODD:
+ return GeneralPath.WIND_EVEN_ODD;
+
+ default:
+ assert false;
+ return GeneralPath.WIND_NON_ZERO;
+ }
+ }
+
+ @Implementation
+ protected boolean isInverseFillType() {
+ throw new UnsupportedOperationException("isInverseFillType");
+ }
+
+ @Implementation
+ protected void toggleInverseFillType() {
+ throw new UnsupportedOperationException("toggleInverseFillType");
+ }
+
+ @Implementation
+ protected boolean isEmpty() {
+ if (!mCachedIsEmpty) {
+ return false;
+ }
+
+ float[] coords = new float[6];
+ mCachedIsEmpty = Boolean.TRUE;
+ for (PathIterator it = mPath.getPathIterator(null); !it.isDone(); it.next()) {
+ int type = it.currentSegment(coords);
+ // if (type != PathIterator.SEG_MOVETO) {
+ // Once we know that the path is not empty, we do not need to check again unless
+ // Path#reset is called.
+ mCachedIsEmpty = false;
+ return false;
+ // }
+ }
+
+ return true;
+ }
+
+ @Implementation
+ protected boolean isRect(RectF rect) {
+ // create an Area that can test if the path is a rect
+ Area area = new Area(mPath);
+ if (area.isRectangular()) {
+ if (rect != null) {
+ fillBounds(rect);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ @Implementation
+ protected void computeBounds(RectF bounds, boolean exact) {
+ fillBounds(bounds);
+ }
+
+ @Implementation
+ protected void incReserve(int extraPtCount) {
+ throw new UnsupportedOperationException("incReserve");
+ }
+
+ @Implementation
+ protected void rMoveTo(float dx, float dy) {
+ dx += mLastX;
+ dy += mLastY;
+ mPath.moveTo(mLastX = dx, mLastY = dy);
+ }
+
+ @Implementation
+ protected void rLineTo(float dx, float dy) {
+ if (!hasPoints()) {
+ mPath.moveTo(mLastX = 0, mLastY = 0);
+ }
+
+ if (Math.abs(dx) < EPSILON && Math.abs(dy) < EPSILON) {
+ // The delta is so small that this shouldn't generate a line
+ return;
+ }
+
+ dx += mLastX;
+ dy += mLastY;
+ mPath.lineTo(mLastX = dx, mLastY = dy);
+ }
+
+ @Implementation
+ protected void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
+ if (!hasPoints()) {
+ mPath.moveTo(mLastX = 0, mLastY = 0);
+ }
+ dx1 += mLastX;
+ dy1 += mLastY;
+ dx2 += mLastX;
+ dy2 += mLastY;
+ mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
+ }
+
+ @Implementation
+ protected void rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3) {
+ if (!hasPoints()) {
+ mPath.moveTo(mLastX = 0, mLastY = 0);
+ }
+ x1 += mLastX;
+ y1 += mLastY;
+ x2 += mLastX;
+ y2 += mLastY;
+ x3 += mLastX;
+ y3 += mLastY;
+ mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
+ }
+
+ @Implementation
+ protected void arcTo(RectF oval, float startAngle, float sweepAngle) {
+ arcTo(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, false);
+ }
+
+ @Implementation
+ protected void arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo) {
+ arcTo(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, forceMoveTo);
+ }
+
+ @Implementation(minSdk = LOLLIPOP)
+ protected void arcTo(
+ float left,
+ float top,
+ float right,
+ float bottom,
+ float startAngle,
+ float sweepAngle,
+ boolean forceMoveTo) {
+ isSimplePath = false;
+ Arc2D arc =
+ new Arc2D.Float(
+ left, top, right - left, bottom - top, -startAngle, -sweepAngle, Arc2D.OPEN);
+ mPath.append(arc, true /*connect*/);
+
+ resetLastPointFromPath();
+ }
+
+ @Implementation
+ protected void close() {
+ if (!hasPoints()) {
+ mPath.moveTo(mLastX = 0, mLastY = 0);
+ }
+ mPath.closePath();
+ }
+
+ @Implementation
+ protected void addRect(RectF rect, Direction dir) {
+ addRect(rect.left, rect.top, rect.right, rect.bottom, dir);
+ }
+
+ @Implementation
+ protected void addRect(float left, float top, float right, float bottom, Path.Direction dir) {
+ moveTo(left, top);
+
+ switch (dir) {
+ case CW:
+ lineTo(right, top);
+ lineTo(right, bottom);
+ lineTo(left, bottom);
+ break;
+ case CCW:
+ lineTo(left, bottom);
+ lineTo(right, bottom);
+ lineTo(right, top);
+ break;
+ }
+
+ close();
+
+ resetLastPointFromPath();
+ }
+
+ @Implementation(minSdk = LOLLIPOP)
+ protected void addOval(float left, float top, float right, float bottom, Path.Direction dir) {
+ mPath.append(new Ellipse2D.Float(left, top, right - left, bottom - top), false);
+ }
+
+ @Implementation
+ protected void addCircle(float x, float y, float radius, Path.Direction dir) {
+ mPath.append(new Ellipse2D.Float(x - radius, y - radius, radius * 2, radius * 2), false);
+ }
+
+ @Implementation(minSdk = LOLLIPOP)
+ protected void addArc(
+ float left, float top, float right, float bottom, float startAngle, float sweepAngle) {
+ mPath.append(
+ new Arc2D.Float(
+ left, top, right - left, bottom - top, -startAngle, -sweepAngle, Arc2D.OPEN),
+ false);
+ }
+
+ @Implementation(minSdk = JELLY_BEAN)
+ protected void addRoundRect(RectF rect, float rx, float ry, Direction dir) {
+ addRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, dir);
+ }
+
+ @Implementation(minSdk = JELLY_BEAN)
+ protected void addRoundRect(RectF rect, float[] radii, Direction dir) {
+ if (rect == null) {
+ throw new NullPointerException("need rect parameter");
+ }
+ addRoundRect(rect.left, rect.top, rect.right, rect.bottom, radii, dir);
+ }
+
+ @Implementation(minSdk = LOLLIPOP)
+ protected void addRoundRect(
+ float left, float top, float right, float bottom, float rx, float ry, Path.Direction dir) {
+ mPath.append(
+ new RoundRectangle2D.Float(left, top, right - left, bottom - top, rx * 2, ry * 2), false);
+ }
+
+ @Implementation(minSdk = LOLLIPOP)
+ protected void addRoundRect(
+ float left, float top, float right, float bottom, float[] radii, Path.Direction dir) {
+ if (radii.length < 8) {
+ throw new ArrayIndexOutOfBoundsException("radii[] needs 8 values");
+ }
+ isSimplePath = false;
+
+ float[] cornerDimensions = new float[radii.length];
+ for (int i = 0; i < radii.length; i++) {
+ cornerDimensions[i] = 2 * radii[i];
+ }
+ mPath.append(
+ new RoundRectangle(left, top, right - left, bottom - top, cornerDimensions), false);
+ }
+
+ @Implementation
+ protected void addPath(Path src, float dx, float dy) {
+ isSimplePath = false;
+ ShadowPath.addPath(realObject, src, AffineTransform.getTranslateInstance(dx, dy));
+ }
+
+ @Implementation
+ protected void addPath(Path src) {
+ isSimplePath = false;
+ ShadowPath.addPath(realObject, src, null);
+ }
+
+ @Implementation
+ protected void addPath(Path src, Matrix matrix) {
+ if (matrix == null) {
+ return;
+ }
+ ShadowPath shadowSrc = extract(src);
+ if (!shadowSrc.isSimplePath) isSimplePath = false;
+
+ ShadowMatrix shadowMatrix = extract(matrix);
+ ShadowPath.addPath(realObject, src, shadowMatrix.getAffineTransform());
+ }
+
+ private static void addPath(Path destPath, Path srcPath, AffineTransform transform) {
+ if (destPath == null) {
+ return;
+ }
+
+ if (srcPath == null) {
+ return;
+ }
+
+ ShadowPath shadowDestPath = extract(destPath);
+ ShadowPath shadowSrcPath = extract(srcPath);
+ if (transform != null) {
+ shadowDestPath.mPath.append(shadowSrcPath.mPath.getPathIterator(transform), false);
+ } else {
+ shadowDestPath.mPath.append(shadowSrcPath.mPath, false);
+ }
+ }
+
+ @Implementation
+ protected void offset(float dx, float dy, Path dst) {
+ if (dst != null) {
+ dst.set(realObject);
+ } else {
+ dst = realObject;
+ }
+ dst.offset(dx, dy);
+ }
+
+ @Implementation
+ protected void offset(float dx, float dy) {
+ GeneralPath newPath = new GeneralPath();
+
+ PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
+
+ newPath.append(iterator, false /*connect*/);
+ mPath = newPath;
+ }
+
+ @Implementation
+ protected void setLastPoint(float dx, float dy) {
+ mLastX = dx;
+ mLastY = dy;
+ }
+
+ @Implementation
+ protected void transform(Matrix matrix, Path dst) {
+ ShadowMatrix shadowMatrix = extract(matrix);
+
+ if (shadowMatrix.hasPerspective()) {
+ Log.w(TAG, "android.graphics.Path#transform() only supports affine transformations.");
+ }
+
+ GeneralPath newPath = new GeneralPath();
+
+ PathIterator iterator = mPath.getPathIterator(shadowMatrix.getAffineTransform());
+ newPath.append(iterator, false /*connect*/);
+
+ if (dst != null) {
+ ShadowPath shadowPath = extract(dst);
+ shadowPath.mPath = newPath;
+ } else {
+ mPath = newPath;
+ }
+ }
+
+ @Implementation
+ protected void transform(Matrix matrix) {
+ transform(matrix, null);
+ }
+
+ /**
+ * Fills the given {@link RectF} with the path bounds.
+ *
+ * @param bounds the RectF to be filled.
+ */
+ public void fillBounds(RectF bounds) {
+ Rectangle2D rect = mPath.getBounds2D();
+ bounds.left = (float) rect.getMinX();
+ bounds.right = (float) rect.getMaxX();
+ bounds.top = (float) rect.getMinY();
+ bounds.bottom = (float) rect.getMaxY();
+ }
+
+ private void resetLastPointFromPath() {
+ Point2D last = mPath.getCurrentPoint();
+ mLastX = (float) last.getX();
+ mLastY = (float) last.getY();
+ }
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPathMeasure.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPathMeasure.java
new file mode 100644
index 000000000..4e5deb62f
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPathMeasure.java
@@ -0,0 +1,58 @@
+package org.robolectric.shadows;
+
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+import java.math.BigDecimal;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadow.api.Shadow;
+
+@Implements(PathMeasure.class)
+public class ShadowPathMeasure {
+
+ private CachedPathIteratorFactory mOriginalPathIterator;
+
+ @Implementation
+ protected void __constructor__(Path path, boolean forceClosed) {
+ if (path != null) {
+ ShadowPath shadowPath = (ShadowPath) Shadow.extract(path);
+ mOriginalPathIterator =
+ new CachedPathIteratorFactory(shadowPath.getJavaShape().getPathIterator(null));
+ }
+ }
+
+ /**
+ * Return the total length of the current contour, or 0 if no path is associated with this measure
+ * object.
+ */
+ @Implementation
+ protected float getLength() {
+ if (mOriginalPathIterator == null) {
+ return 0;
+ }
+
+ return mOriginalPathIterator.iterator().getTotalLength();
+ }
+
+ /** Note: This is not mathematically correct. */
+ @Implementation
+ protected boolean getPosTan(float distance, float pos[], float tan[]) {
+ if (pos != null && pos.length < 2 || tan != null && tan.length < 2) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ // This is not mathematically correct, but the simulation keeps the support library happy.
+ if (getLength() > 0) {
+ pos[0] = round(distance / getLength(), 4);
+ pos[1] = round(distance / getLength(), 4);
+ }
+
+ return true;
+ }
+
+ private static float round(float d, int decimalPlace) {
+ BigDecimal bd = new BigDecimal(d);
+ bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
+ return bd.floatValue();
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPathParser.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPathParser.java
index a127f383c..1ababc0e4 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPathParser.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPathParser.java
@@ -2,21 +2,59 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.N;
+import android.graphics.Path;
+import android.util.Log;
import android.util.PathParser;
+import android.util.PathParser.PathData;
+import java.util.ArrayList;
+import java.util.Arrays;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@Implements(value = PathParser.class, minSdk = N, isInAndroidSdk = false)
public class ShadowPathParser {
+ static final String LOGTAG = ShadowPathParser.class.getSimpleName();
+
@Implementation
- public static long nCreatePathDataFromString(String pathString, int stringLength) {
- return 1;
+ protected static Path createPathFromPathData(String pathData) {
+ Path path = new Path();
+ PathDataNode[] nodes = createNodesFromPathData(pathData);
+ if (nodes != null) {
+ PathDataNode.nodesToPath(nodes, path);
+ return path;
+ }
+ return null;
+ }
+
+ public static PathDataNode[] createNodesFromPathData(String pathData) {
+ if (pathData == null) {
+ return null;
+ }
+ int start = 0;
+ int end = 1;
+
+ ArrayList<PathDataNode> list = new ArrayList<PathDataNode>();
+ while (end < pathData.length()) {
+ end = nextStart(pathData, end);
+ String s = pathData.substring(start, end).trim();
+ if (s.length() > 0) {
+ float[] val = getFloats(s);
+ addNode(list, s.charAt(0), val);
+ }
+
+ start = end;
+ end++;
+ }
+ if ((end - start) == 1 && start < pathData.length()) {
+ addNode(list, pathData.charAt(start), new float[0]);
+ }
+ return list.toArray(new PathDataNode[list.size()]);
}
@Implementation
- public static boolean nInterpolatePathData(long outDataPtr, long fromDataPtr,
- long toDataPtr, float fraction) {
+ protected static boolean interpolatePathData(
+ PathData outData, PathData fromData, PathData toData, float fraction) {
return true;
}
@@ -24,4 +62,567 @@ public class ShadowPathParser {
public static boolean nCanMorph(long fromDataPtr, long toDataPtr) {
return true;
}
-} \ No newline at end of file
+
+ private static int nextStart(String s, int end) {
+ char c;
+
+ while (end < s.length()) {
+ c = s.charAt(end);
+ if (((c - 'A') * (c - 'Z') <= 0) || (((c - 'a') * (c - 'z') <= 0))) {
+ return end;
+ }
+ end++;
+ }
+ return end;
+ }
+
+ private static void addNode(ArrayList<PathDataNode> list, char cmd, float[] val) {
+ list.add(new PathDataNode(cmd, val));
+ }
+
+ private static class ExtractFloatResult {
+ // We need to return the position of the next separator and whether the
+ // next float starts with a '-'.
+ int mEndPosition;
+ boolean mEndWithNegSign;
+ }
+
+ private static float[] getFloats(String s) {
+ if (s.charAt(0) == 'z' | s.charAt(0) == 'Z') {
+ return new float[0];
+ }
+ try {
+ float[] results = new float[s.length()];
+ int count = 0;
+ int startPosition = 1;
+ int endPosition = 0;
+
+ ExtractFloatResult result = new ExtractFloatResult();
+ int totalLength = s.length();
+
+ // The startPosition should always be the first character of the
+ // current number, and endPosition is the character after the current
+ // number.
+ while (startPosition < totalLength) {
+ extract(s, startPosition, result);
+ endPosition = result.mEndPosition;
+
+ if (startPosition < endPosition) {
+ results[count++] = Float.parseFloat(s.substring(startPosition, endPosition));
+ }
+
+ if (result.mEndWithNegSign) {
+ // Keep the '-' sign with next number.
+ startPosition = endPosition;
+ } else {
+ startPosition = endPosition + 1;
+ }
+ }
+ return Arrays.copyOf(results, count);
+ } catch (NumberFormatException e) {
+ Log.e(LOGTAG, "error in parsing \"" + s + "\"");
+ throw e;
+ }
+ }
+
+ private static void extract(String s, int start, ExtractFloatResult result) {
+ // Now looking for ' ', ',' or '-' from the start.
+ int currentIndex = start;
+ boolean foundSeparator = false;
+ result.mEndWithNegSign = false;
+ for (; currentIndex < s.length(); currentIndex++) {
+ char currentChar = s.charAt(currentIndex);
+ switch (currentChar) {
+ case ' ':
+ case ',':
+ foundSeparator = true;
+ break;
+ case '-':
+ if (currentIndex != start) {
+ foundSeparator = true;
+ result.mEndWithNegSign = true;
+ }
+ break;
+ }
+ if (foundSeparator) {
+ break;
+ }
+ }
+ // When there is nothing found, then we put the end position to the end
+ // of the string.
+ result.mEndPosition = currentIndex;
+ }
+
+ public static class PathDataNode {
+ private char mType;
+ private float[] mParams;
+
+ private PathDataNode(char type, float[] params) {
+ mType = type;
+ mParams = params;
+ }
+
+ private PathDataNode(PathDataNode n) {
+ mType = n.mType;
+ mParams = Arrays.copyOf(n.mParams, n.mParams.length);
+ }
+
+ /**
+ * Convert an array of PathDataNode to Path.
+ *
+ * @param node The source array of PathDataNode.
+ * @param path The target Path object.
+ */
+ public static void nodesToPath(PathDataNode[] node, Path path) {
+ float[] current = new float[4];
+ char previousCommand = 'm';
+ for (int i = 0; i < node.length; i++) {
+ addCommand(path, current, previousCommand, node[i].mType, node[i].mParams);
+ previousCommand = node[i].mType;
+ }
+ }
+
+ /**
+ * The current PathDataNode will be interpolated between the <code>nodeFrom</code> and <code>
+ * nodeTo</code> according to the <code>fraction</code>.
+ *
+ * @param nodeFrom The start value as a PathDataNode.
+ * @param nodeTo The end value as a PathDataNode
+ * @param fraction The fraction to interpolate.
+ */
+ public void interpolatePathDataNode(
+ PathDataNode nodeFrom, PathDataNode nodeTo, float fraction) {
+ for (int i = 0; i < nodeFrom.mParams.length; i++) {
+ mParams[i] = nodeFrom.mParams[i] * (1 - fraction) + nodeTo.mParams[i] * fraction;
+ }
+ }
+
+ private static void addCommand(
+ Path path, float[] current, char previousCmd, char cmd, float[] val) {
+
+ int incr = 2;
+ float currentX = current[0];
+ float currentY = current[1];
+ float ctrlPointX = current[2];
+ float ctrlPointY = current[3];
+ float reflectiveCtrlPointX;
+ float reflectiveCtrlPointY;
+
+ switch (cmd) {
+ case 'z':
+ case 'Z':
+ path.close();
+ return;
+ case 'm':
+ case 'M':
+ case 'l':
+ case 'L':
+ case 't':
+ case 'T':
+ incr = 2;
+ break;
+ case 'h':
+ case 'H':
+ case 'v':
+ case 'V':
+ incr = 1;
+ break;
+ case 'c':
+ case 'C':
+ incr = 6;
+ break;
+ case 's':
+ case 'S':
+ case 'q':
+ case 'Q':
+ incr = 4;
+ break;
+ case 'a':
+ case 'A':
+ incr = 7;
+ break;
+ }
+ for (int k = 0; k < val.length; k += incr) {
+ switch (cmd) {
+ case 'm': // moveto - Start a new sub-path (relative)
+ path.rMoveTo(val[k + 0], val[k + 1]);
+ currentX += val[k + 0];
+ currentY += val[k + 1];
+ break;
+ case 'M': // moveto - Start a new sub-path
+ path.moveTo(val[k + 0], val[k + 1]);
+ currentX = val[k + 0];
+ currentY = val[k + 1];
+ break;
+ case 'l': // lineto - Draw a line from the current point (relative)
+ path.rLineTo(val[k + 0], val[k + 1]);
+ currentX += val[k + 0];
+ currentY += val[k + 1];
+ break;
+ case 'L': // lineto - Draw a line from the current point
+ path.lineTo(val[k + 0], val[k + 1]);
+ currentX = val[k + 0];
+ currentY = val[k + 1];
+ break;
+ case 'z': // closepath - Close the current subpath
+ case 'Z': // closepath - Close the current subpath
+ path.close();
+ break;
+ case 'h': // horizontal lineto - Draws a horizontal line (relative)
+ path.rLineTo(val[k + 0], 0);
+ currentX += val[k + 0];
+ break;
+ case 'H': // horizontal lineto - Draws a horizontal line
+ path.lineTo(val[k + 0], currentY);
+ currentX = val[k + 0];
+ break;
+ case 'v': // vertical lineto - Draws a vertical line from the current point (r)
+ path.rLineTo(0, val[k + 0]);
+ currentY += val[k + 0];
+ break;
+ case 'V': // vertical lineto - Draws a vertical line from the current point
+ path.lineTo(currentX, val[k + 0]);
+ currentY = val[k + 0];
+ break;
+ case 'c': // curveto - Draws a cubic Bézier curve (relative)
+ path.rCubicTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3], val[k + 4], val[k + 5]);
+
+ ctrlPointX = currentX + val[k + 2];
+ ctrlPointY = currentY + val[k + 3];
+ currentX += val[k + 4];
+ currentY += val[k + 5];
+
+ break;
+ case 'C': // curveto - Draws a cubic Bézier curve
+ path.cubicTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3], val[k + 4], val[k + 5]);
+ currentX = val[k + 4];
+ currentY = val[k + 5];
+ ctrlPointX = val[k + 2];
+ ctrlPointY = val[k + 3];
+ break;
+ case 's': // smooth curveto - Draws a cubic Bézier curve (reflective cp)
+ reflectiveCtrlPointX = 0;
+ reflectiveCtrlPointY = 0;
+ if (previousCmd == 'c'
+ || previousCmd == 's'
+ || previousCmd == 'C'
+ || previousCmd == 'S') {
+ reflectiveCtrlPointX = currentX - ctrlPointX;
+ reflectiveCtrlPointY = currentY - ctrlPointY;
+ }
+ path.rCubicTo(
+ reflectiveCtrlPointX,
+ reflectiveCtrlPointY,
+ val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3]);
+
+ ctrlPointX = currentX + val[k + 0];
+ ctrlPointY = currentY + val[k + 1];
+ currentX += val[k + 2];
+ currentY += val[k + 3];
+ break;
+ case 'S': // shorthand/smooth curveto Draws a cubic Bézier curve(reflective cp)
+ reflectiveCtrlPointX = currentX;
+ reflectiveCtrlPointY = currentY;
+ if (previousCmd == 'c'
+ || previousCmd == 's'
+ || previousCmd == 'C'
+ || previousCmd == 'S') {
+ reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
+ reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
+ }
+ path.cubicTo(
+ reflectiveCtrlPointX,
+ reflectiveCtrlPointY,
+ val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3]);
+ ctrlPointX = val[k + 0];
+ ctrlPointY = val[k + 1];
+ currentX = val[k + 2];
+ currentY = val[k + 3];
+ break;
+ case 'q': // Draws a quadratic Bézier (relative)
+ path.rQuadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
+ ctrlPointX = currentX + val[k + 0];
+ ctrlPointY = currentY + val[k + 1];
+ currentX += val[k + 2];
+ currentY += val[k + 3];
+ break;
+ case 'Q': // Draws a quadratic Bézier
+ path.quadTo(val[k + 0], val[k + 1], val[k + 2], val[k + 3]);
+ ctrlPointX = val[k + 0];
+ ctrlPointY = val[k + 1];
+ currentX = val[k + 2];
+ currentY = val[k + 3];
+ break;
+ case 't': // Draws a quadratic Bézier curve(reflective control point)(relative)
+ reflectiveCtrlPointX = 0;
+ reflectiveCtrlPointY = 0;
+ if (previousCmd == 'q'
+ || previousCmd == 't'
+ || previousCmd == 'Q'
+ || previousCmd == 'T') {
+ reflectiveCtrlPointX = currentX - ctrlPointX;
+ reflectiveCtrlPointY = currentY - ctrlPointY;
+ }
+ path.rQuadTo(reflectiveCtrlPointX, reflectiveCtrlPointY, val[k + 0], val[k + 1]);
+ ctrlPointX = currentX + reflectiveCtrlPointX;
+ ctrlPointY = currentY + reflectiveCtrlPointY;
+ currentX += val[k + 0];
+ currentY += val[k + 1];
+ break;
+ case 'T': // Draws a quadratic Bézier curve (reflective control point)
+ reflectiveCtrlPointX = currentX;
+ reflectiveCtrlPointY = currentY;
+ if (previousCmd == 'q'
+ || previousCmd == 't'
+ || previousCmd == 'Q'
+ || previousCmd == 'T') {
+ reflectiveCtrlPointX = 2 * currentX - ctrlPointX;
+ reflectiveCtrlPointY = 2 * currentY - ctrlPointY;
+ }
+ path.quadTo(reflectiveCtrlPointX, reflectiveCtrlPointY, val[k + 0], val[k + 1]);
+ ctrlPointX = reflectiveCtrlPointX;
+ ctrlPointY = reflectiveCtrlPointY;
+ currentX = val[k + 0];
+ currentY = val[k + 1];
+ break;
+ case 'a': // Draws an elliptical arc
+ // (rx ry x-axis-rotation large-arc-flag sweep-flag x y)
+ drawArc(
+ path,
+ currentX,
+ currentY,
+ val[k + 5] + currentX,
+ val[k + 6] + currentY,
+ val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3] != 0,
+ val[k + 4] != 0);
+ currentX += val[k + 5];
+ currentY += val[k + 6];
+ ctrlPointX = currentX;
+ ctrlPointY = currentY;
+ break;
+ case 'A': // Draws an elliptical arc
+ drawArc(
+ path,
+ currentX,
+ currentY,
+ val[k + 5],
+ val[k + 6],
+ val[k + 0],
+ val[k + 1],
+ val[k + 2],
+ val[k + 3] != 0,
+ val[k + 4] != 0);
+ currentX = val[k + 5];
+ currentY = val[k + 6];
+ ctrlPointX = currentX;
+ ctrlPointY = currentY;
+ break;
+ }
+ previousCmd = cmd;
+ }
+ current[0] = currentX;
+ current[1] = currentY;
+ current[2] = ctrlPointX;
+ current[3] = ctrlPointY;
+ }
+
+ private static void drawArc(
+ Path p,
+ float x0,
+ float y0,
+ float x1,
+ float y1,
+ float a,
+ float b,
+ float theta,
+ boolean isMoreThanHalf,
+ boolean isPositiveArc) {
+
+ /* Convert rotation angle from degrees to radians */
+ double thetaD = Math.toRadians(theta);
+ /* Pre-compute rotation matrix entries */
+ double cosTheta = Math.cos(thetaD);
+ double sinTheta = Math.sin(thetaD);
+ /* Transform (x0, y0) and (x1, y1) into unit space */
+ /* using (inverse) rotation, followed by (inverse) scale */
+ double x0p = (x0 * cosTheta + y0 * sinTheta) / a;
+ double y0p = (-x0 * sinTheta + y0 * cosTheta) / b;
+ double x1p = (x1 * cosTheta + y1 * sinTheta) / a;
+ double y1p = (-x1 * sinTheta + y1 * cosTheta) / b;
+
+ /* Compute differences and averages */
+ double dx = x0p - x1p;
+ double dy = y0p - y1p;
+ double xm = (x0p + x1p) / 2;
+ double ym = (y0p + y1p) / 2;
+ /* Solve for intersecting unit circles */
+ double dsq = dx * dx + dy * dy;
+ if (dsq == 0.0) {
+ Log.w(LOGTAG, " Points are coincident");
+ return; /* Points are coincident */
+ }
+ double disc = 1.0 / dsq - 1.0 / 4.0;
+ if (disc < 0.0) {
+ Log.w(LOGTAG, "Points are too far apart " + dsq);
+ float adjust = (float) (Math.sqrt(dsq) / 1.99999);
+ drawArc(p, x0, y0, x1, y1, a * adjust, b * adjust, theta, isMoreThanHalf, isPositiveArc);
+ return; /* Points are too far apart */
+ }
+ double s = Math.sqrt(disc);
+ double sdx = s * dx;
+ double sdy = s * dy;
+ double cx;
+ double cy;
+ if (isMoreThanHalf == isPositiveArc) {
+ cx = xm - sdy;
+ cy = ym + sdx;
+ } else {
+ cx = xm + sdy;
+ cy = ym - sdx;
+ }
+
+ double eta0 = Math.atan2((y0p - cy), (x0p - cx));
+
+ double eta1 = Math.atan2((y1p - cy), (x1p - cx));
+
+ double sweep = (eta1 - eta0);
+ if (isPositiveArc != (sweep >= 0)) {
+ if (sweep > 0) {
+ sweep -= 2 * Math.PI;
+ } else {
+ sweep += 2 * Math.PI;
+ }
+ }
+
+ cx *= a;
+ cy *= b;
+ double tcx = cx;
+ cx = cx * cosTheta - cy * sinTheta;
+ cy = tcx * sinTheta + cy * cosTheta;
+
+ arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep);
+ }
+
+ /**
+ * Converts an arc to cubic Bezier segments and records them in p.
+ *
+ * @param p The target for the cubic Bezier segments
+ * @param cx The x coordinate center of the ellipse
+ * @param cy The y coordinate center of the ellipse
+ * @param a The radius of the ellipse in the horizontal direction
+ * @param b The radius of the ellipse in the vertical direction
+ * @param e1x E(eta1) x coordinate of the starting point of the arc
+ * @param e1y E(eta2) y coordinate of the starting point of the arc
+ * @param theta The angle that the ellipse bounding rectangle makes with horizontal plane
+ * @param start The start angle of the arc on the ellipse
+ * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
+ */
+ private static void arcToBezier(
+ Path p,
+ double cx,
+ double cy,
+ double a,
+ double b,
+ double e1x,
+ double e1y,
+ double theta,
+ double start,
+ double sweep) {
+ // Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html
+ // and http://www.spaceroots.org/documents/ellipse/node22.html
+
+ // Maximum of 45 degrees per cubic Bezier segment
+ int numSegments = Math.abs((int) Math.ceil(sweep * 4 / Math.PI));
+
+ double eta1 = start;
+ double cosTheta = Math.cos(theta);
+ double sinTheta = Math.sin(theta);
+ double cosEta1 = Math.cos(eta1);
+ double sinEta1 = Math.sin(eta1);
+ double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1);
+ double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1);
+
+ double anglePerSegment = sweep / numSegments;
+ for (int i = 0; i < numSegments; i++) {
+ double eta2 = eta1 + anglePerSegment;
+ double sinEta2 = Math.sin(eta2);
+ double cosEta2 = Math.cos(eta2);
+ double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2);
+ double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2);
+ double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2;
+ double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2;
+ double tanDiff2 = Math.tan((eta2 - eta1) / 2);
+ double alpha = Math.sin(eta2 - eta1) * (Math.sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3;
+ double q1x = e1x + alpha * ep1x;
+ double q1y = e1y + alpha * ep1y;
+ double q2x = e2x - alpha * ep2x;
+ double q2y = e2y - alpha * ep2y;
+
+ p.cubicTo((float) q1x, (float) q1y, (float) q2x, (float) q2y, (float) e2x, (float) e2y);
+ eta1 = eta2;
+ e1x = e2x;
+ e1y = e2y;
+ ep1x = ep2x;
+ ep1y = ep2y;
+ }
+ }
+ }
+
+ @Implements(value = PathParser.PathData.class, minSdk = N, isInAndroidSdk = false)
+ public static class ShadowPathData {
+ long mNativePathData = 0;
+
+ @Implementation
+ public void __constructor__() {
+ // mNativePathData = nCreateEmptyPathData();
+ }
+
+ @Implementation
+ public void __constructor__(PathParser.PathData data) {
+ // mNativePathData = nCreatePathData(data.mNativePathData);
+ }
+
+ @Implementation
+ public void __constructor__(String pathString) {
+ // mNativePathData = nCreatePathDataFromString(pathString, pathString.length());
+ // if (mNativePathData == 0) {
+ // throw new IllegalArgumentException("Invalid pathData: " + pathString);
+ // }
+ }
+
+ @Implementation
+ public long getNativePtr() {
+ return mNativePathData;
+ }
+
+ /**
+ * Update the path data to match the source. Before calling this, make sure canMorph(target,
+ * source) is true.
+ *
+ * @param source The source path represented in PathData
+ */
+ @Implementation
+ public void setPathData(PathParser.PathData source) {
+ // nSetPathData(mNativePathData, source.mNativePathData);
+ }
+
+ @Override
+ @Implementation
+ protected void finalize() throws Throwable {
+ if (mNativePathData != 0) {
+ // nFinalize(mNativePathData);
+ mNativePathData = 0;
+ }
+ super.finalize();
+ }
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPeerHandle.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPeerHandle.java
index 105ffd624..c94d5dfdb 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPeerHandle.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPeerHandle.java
@@ -6,7 +6,6 @@ import android.net.wifi.aware.PeerHandle;
import org.robolectric.annotation.Implements;
import org.robolectric.util.ReflectionHelpers;
-/** Shadow for {@link PeerHandle}. */
@Implements(value = PeerHandle.class, minSdk = O)
public class ShadowPeerHandle {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPendingIntent.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPendingIntent.java
index 3f18118c4..d508cb6bd 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPendingIntent.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPendingIntent.java
@@ -60,37 +60,37 @@ public class ShadowPendingIntent {
private boolean canceled;
@Implementation
- public static PendingIntent getActivity(
+ protected static PendingIntent getActivity(
Context context, int requestCode, @NonNull Intent intent, int flags) {
return create(context, new Intent[] {intent}, Type.ACTIVITY, requestCode, flags);
}
@Implementation
- public static PendingIntent getActivity(
+ protected static PendingIntent getActivity(
Context context, int requestCode, @NonNull Intent intent, int flags, Bundle options) {
return create(context, new Intent[] {intent}, Type.ACTIVITY, requestCode, flags);
}
@Implementation
- public static PendingIntent getActivities(
+ protected static PendingIntent getActivities(
Context context, int requestCode, @NonNull Intent[] intents, int flags) {
return create(context, intents, Type.ACTIVITY, requestCode, flags);
}
@Implementation
- public static PendingIntent getActivities(
+ protected static PendingIntent getActivities(
Context context, int requestCode, @NonNull Intent[] intents, int flags, Bundle options) {
return create(context, intents, Type.ACTIVITY, requestCode, flags);
}
@Implementation
- public static PendingIntent getBroadcast(
+ protected static PendingIntent getBroadcast(
Context context, int requestCode, @NonNull Intent intent, int flags) {
return create(context, new Intent[] {intent}, Type.BROADCAST, requestCode, flags);
}
@Implementation
- public static PendingIntent getService(
+ protected static PendingIntent getService(
Context context, int requestCode, @NonNull Intent intent, int flags) {
return create(context, new Intent[] {intent}, Type.SERVICE, requestCode, flags);
}
@@ -103,7 +103,7 @@ public class ShadowPendingIntent {
@Implementation
@SuppressWarnings("ReferenceEquality")
- public void cancel() {
+ protected void cancel() {
for (Iterator<PendingIntent> i = createdIntents.iterator(); i.hasNext(); ) {
PendingIntent pendingIntent = i.next();
if (pendingIntent == realPendingIntent) {
@@ -115,7 +115,7 @@ public class ShadowPendingIntent {
}
@Implementation
- public void send() throws CanceledException {
+ protected void send() throws CanceledException {
send(savedContext, 0, null);
}
@@ -125,9 +125,8 @@ public class ShadowPendingIntent {
send(savedContext, code, null, onFinished, handler);
}
-
@Implementation
- public void send(Context context, int code, Intent intent) throws CanceledException {
+ protected void send(Context context, int code, Intent intent) throws CanceledException {
send(context, code, intent, null, null);
}
@@ -196,7 +195,7 @@ public class ShadowPendingIntent {
}
@Implementation
- public IntentSender getIntentSender() {
+ protected IntentSender getIntentSender() {
return new RoboIntentSender(realPendingIntent);
}
@@ -284,12 +283,12 @@ public class ShadowPendingIntent {
}
@Implementation
- public String getTargetPackage() {
+ protected String getTargetPackage() {
return getCreatorPackage();
}
@Implementation(minSdk = JELLY_BEAN_MR1)
- public String getCreatorPackage() {
+ protected String getCreatorPackage() {
return (creatorPackage == null)
? RuntimeEnvironment.application.getPackageName()
: creatorPackage;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPicture.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPicture.java
index 82deb6ac0..d12fe9b59 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPicture.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPicture.java
@@ -16,32 +16,32 @@ public class ShadowPicture {
private int height;
@Implementation
- public void __constructor__() {}
+ protected void __constructor__() {}
@Implementation(minSdk = LOLLIPOP)
- public void __constructor__(long nativePicture) {}
+ protected void __constructor__(long nativePicture) {}
@Implementation(maxSdk = KITKAT_WATCH)
- public void __constructor__(int nativePicture, boolean fromStream) {}
+ protected void __constructor__(int nativePicture, boolean fromStream) {}
@Implementation
- public void __constructor__(Picture src) {
+ protected void __constructor__(Picture src) {
width = src.getWidth();
height = src.getHeight();
}
@Implementation
- public int getWidth() {
+ protected int getWidth() {
return width;
}
@Implementation
- public int getHeight() {
+ protected int getHeight() {
return height;
}
@Implementation
- public Canvas beginRecording(int width, int height) {
+ protected Canvas beginRecording(int width, int height) {
this.width = width;
this.height = height;
return new Canvas(Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888));
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPopupMenu.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPopupMenu.java
index d7c5bec6b..4c5727168 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPopupMenu.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPopupMenu.java
@@ -19,20 +19,20 @@ public class ShadowPopupMenu {
private PopupMenu.OnMenuItemClickListener onMenuItemClickListener;
@Implementation
- public void show() {
+ protected void show() {
this.isShowing = true;
setLatestPopupMenu(this);
directlyOn(realPopupMenu, PopupMenu.class).show();
}
@Implementation
- public void dismiss() {
+ protected void dismiss() {
this.isShowing = false;
directlyOn(realPopupMenu, PopupMenu.class).dismiss();
}
@Implementation
- public void setOnMenuItemClickListener(PopupMenu.OnMenuItemClickListener listener) {
+ protected void setOnMenuItemClickListener(PopupMenu.OnMenuItemClickListener listener) {
this.onMenuItemClickListener = listener;
directlyOn(realPopupMenu, PopupMenu.class).setOnMenuItemClickListener(listener);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPopupWindow.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPopupWindow.java
index 427aa441f..d9210ab80 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPopupWindow.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPopupWindow.java
@@ -16,7 +16,7 @@ public class ShadowPopupWindow {
private PopupWindow realPopupWindow;
@Implementation
- public void invokePopup(WindowManager.LayoutParams p) {
+ protected void invokePopup(WindowManager.LayoutParams p) {
ShadowApplication.getInstance().setLatestPopupWindow(realPopupWindow);
directlyOn(realPopupWindow,
PopupWindow.class,
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPorterDuffColorFilter.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPorterDuffColorFilter.java
index 2827072be..b22daa229 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPorterDuffColorFilter.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPorterDuffColorFilter.java
@@ -7,25 +7,39 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
+
@Implements(PorterDuffColorFilter.class)
public class ShadowPorterDuffColorFilter {
private int color;
private PorterDuff.Mode mode;
+ @RealObject private PorterDuffColorFilter realPorterDuffColorFilter;
+
@Implementation
- public void __constructor__(int color, PorterDuff.Mode mode) {
+ protected void __constructor__(int color, PorterDuff.Mode mode) {
+ // We need these copies because before Lollipop, PorterDuffColorFilter had no fields, it would
+ // just delegate to a native instance. If we remove them, the shadow cannot access the fields
+ // on KitKat and earlier.
this.color = color;
this.mode = mode;
+ Shadow.invokeConstructor(
+ PorterDuffColorFilter.class,
+ realPorterDuffColorFilter,
+ ClassParameter.from(int.class, color),
+ ClassParameter.from(PorterDuff.Mode.class, mode));
}
@Implementation(minSdk = LOLLIPOP, maxSdk = P)
- public void setColor(int color) {
+ protected void setColor(int color) {
this.color = color;
}
@Implementation(minSdk = LOLLIPOP, maxSdk = P)
- public void setMode(PorterDuff.Mode mode) {
+ protected void setMode(PorterDuff.Mode mode) {
this.mode = mode;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPowerManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPowerManager.java
index b54a5b211..010088497 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPowerManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPowerManager.java
@@ -32,14 +32,14 @@ public class ShadowPowerManager {
private Map<String, Boolean> ignoringBatteryOptimizations = new HashMap<>();
@Implementation
- public PowerManager.WakeLock newWakeLock(int flags, String tag) {
+ protected PowerManager.WakeLock newWakeLock(int flags, String tag) {
PowerManager.WakeLock wl = Shadow.newInstanceOf(PowerManager.WakeLock.class);
getInstance().addWakeLock(wl);
return wl;
}
@Implementation
- public boolean isScreenOn() {
+ protected boolean isScreenOn() {
return isScreenOn;
}
@@ -48,7 +48,7 @@ public class ShadowPowerManager {
}
@Implementation(minSdk = LOLLIPOP)
- public boolean isInteractive() {
+ protected boolean isInteractive() {
return isInteractive;
}
@@ -57,12 +57,13 @@ public class ShadowPowerManager {
}
@Implementation(minSdk = LOLLIPOP)
- public boolean isPowerSaveMode() {
+ protected boolean isPowerSaveMode() {
return isPowerSaveMode;
}
- @HiddenApi @Implementation(minSdk = KITKAT_WATCH)
- protected void setPowerSaveMode(boolean powerSaveMode) {
+ @HiddenApi
+ @Implementation(minSdk = KITKAT_WATCH)
+ protected boolean setPowerSaveMode(boolean powerSaveMode) {
final Context context = RuntimeEnvironment.application;
final int perm = context.getPackageManager()
.checkPermission(permission.DEVICE_POWER, context.getPackageName());
@@ -71,6 +72,7 @@ public class ShadowPowerManager {
"You need DEVICE_POWER permission to: set the device power-save mode");
}
isPowerSaveMode = powerSaveMode;
+ return true;
}
/**
@@ -84,7 +86,7 @@ public class ShadowPowerManager {
private Map<Integer, Boolean> supportedWakeLockLevels = new HashMap<>();
@Implementation(minSdk = LOLLIPOP)
- public boolean isWakeLockLevelSupported(int level) {
+ protected boolean isWakeLockLevelSupported(int level) {
return supportedWakeLockLevels.containsKey(level) ? supportedWakeLockLevels.get(level) : false;
}
@@ -125,7 +127,7 @@ public class ShadowPowerManager {
}
@Implementation(minSdk = M)
- public boolean isIgnoringBatteryOptimizations(String packageName) {
+ protected boolean isIgnoringBatteryOptimizations(String packageName) {
Boolean result = ignoringBatteryOptimizations.get(packageName);
return result == null ? false : result;
}
@@ -157,12 +159,12 @@ public class ShadowPowerManager {
private WorkSource workSource = null;
@Implementation
- public void acquire() {
+ protected void acquire() {
acquire(0);
}
@Implementation
- public synchronized void acquire(long timeout) {
+ protected synchronized void acquire(long timeout) {
if (refCounted) {
refCount++;
} else {
@@ -171,7 +173,7 @@ public class ShadowPowerManager {
}
@Implementation
- public synchronized void release() {
+ protected synchronized void release() {
if (refCounted) {
if (--refCount < 0) throw new RuntimeException("WakeLock under-locked");
} else {
@@ -180,7 +182,7 @@ public class ShadowPowerManager {
}
@Implementation
- public synchronized boolean isHeld() {
+ protected synchronized boolean isHeld() {
return refCounted ? refCount > 0 : locked;
}
@@ -194,12 +196,12 @@ public class ShadowPowerManager {
}
@Implementation
- public void setReferenceCounted(boolean value) {
+ protected void setReferenceCounted(boolean value) {
refCounted = value;
}
@Implementation
- public synchronized void setWorkSource(WorkSource ws) {
+ protected synchronized void setWorkSource(WorkSource ws) {
workSource = ws;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowProcess.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowProcess.java
index 840697ab9..536fce060 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowProcess.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowProcess.java
@@ -119,7 +119,7 @@ public class ShadowProcess {
// android.os.Process.myUid(), which persists between tests.
}
- private static int getRandomApplicationUid() {
+ static int getRandomApplicationUid() {
// UIDs are randomly initialized to prevent tests from depending on any given value. Tests
// should access the current process UID via android.os.Process::myUid().
return ThreadLocalRandom.current()
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowProgressDialog.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowProgressDialog.java
index 6bac60d9c..280eeefa7 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowProgressDialog.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowProgressDialog.java
@@ -30,7 +30,7 @@ public class ShadowProgressDialog extends ShadowAlertDialog {
}
@Implementation
- public void setProgressStyle(int style) {
+ protected void setProgressStyle(int style) {
mProgressStyle = style;
directlyOn(realProgressDialog, ProgressDialog.class).setProgressStyle(style);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRecordingCanvas.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRecordingCanvas.java
new file mode 100644
index 000000000..e22e1a02a
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRecordingCanvas.java
@@ -0,0 +1,29 @@
+// BEGIN-INTERNAL
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.Q;
+
+import android.graphics.RecordingCanvas;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(value = RecordingCanvas.class, isInAndroidSdk = false, minSdk = Q)
+public class ShadowRecordingCanvas extends ShadowCanvas {
+
+ @Implementation
+ protected static long nCreateDisplayListCanvas(long node, int width, int height) {
+ return 1;
+ }
+
+ @Config
+ protected static long nCreateDisplayListCanvas(int width, int height) {
+ return 1;
+ }
+
+ @Config
+ protected static long nCreateDisplayListCanvas() {
+ return 1;
+ }
+}
+// END-INTERNAL \ No newline at end of file
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRegion.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRegion.java
index 75217ba95..067f8ad2e 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRegion.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRegion.java
@@ -1,16 +1,17 @@
package org.robolectric.shadows;
import android.graphics.Region;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@Implements(Region.class)
public class ShadowRegion {
- public static int nextId = 1;
+ public static long nextId = 1;
@HiddenApi @Implementation
- public static int nativeConstructor() {
- return nextId++;
+ public static Number nativeConstructor() {
+ return RuntimeEnvironment.castNativePtr(nextId++);
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRemoteCallbackList.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRemoteCallbackList.java
index 07b1d972b..4bf84b373 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRemoteCallbackList.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRemoteCallbackList.java
@@ -33,12 +33,12 @@ public class ShadowRemoteCallbackList<E extends IInterface> {
}
@Implementation
- public boolean register(E callback) {
+ protected boolean register(E callback) {
return register(callback, null);
}
@Implementation
- public boolean register(E callback, Object cookie) {
+ protected boolean register(E callback, Object cookie) {
synchronized (callbacks) {
if (killed) {
return false;
@@ -56,7 +56,7 @@ public class ShadowRemoteCallbackList<E extends IInterface> {
}
@Implementation
- public boolean unregister(E callback) {
+ protected boolean unregister(E callback) {
synchronized (callbacks) {
Callback cb = callbacks.remove(callback.asBinder());
if (cb != null) {
@@ -68,7 +68,7 @@ public class ShadowRemoteCallbackList<E extends IInterface> {
}
@Implementation
- public void kill() {
+ protected void kill() {
synchronized (callbacks) {
for (Callback cb : callbacks.values()) {
cb.callback.asBinder().unlinkToDeath(cb, 0);
@@ -79,15 +79,15 @@ public class ShadowRemoteCallbackList<E extends IInterface> {
}
@Implementation
- public void onCallbackDied(E callback) {}
+ protected void onCallbackDied(E callback) {}
@Implementation
- public void onCallbackDied(E callback, Object cookie) {
+ protected void onCallbackDied(E callback, Object cookie) {
onCallbackDied(callback);
}
@Implementation
- public int beginBroadcast() {
+ protected int beginBroadcast() {
synchronized (callbacks) {
if (broadcastCount > 0) {
throw new IllegalStateException("beginBroadcast() called while already in a broadcast");
@@ -109,17 +109,17 @@ public class ShadowRemoteCallbackList<E extends IInterface> {
}
@Implementation
- public E getBroadcastItem(int index) {
+ protected E getBroadcastItem(int index) {
return ((Callback) activeBroadcast[index]).callback;
}
@Implementation
- public Object getBroadcastCookie(int index) {
+ protected Object getBroadcastCookie(int index) {
return ((Callback) activeBroadcast[index]).cookie;
}
@Implementation
- public void finishBroadcast() {
+ protected void finishBroadcast() {
if (broadcastCount < 0) {
throw new IllegalStateException("finishBroadcast() called outside of a broadcast");
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRenderNode.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRenderNode.java
index ae565614f..83b7ac6c4 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRenderNode.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRenderNode.java
@@ -1,12 +1,13 @@
+// BEGIN-INTERNAL
package org.robolectric.shadows;
-import static android.os.Build.VERSION_CODES.LOLLIPOP;
+import static android.os.Build.VERSION_CODES.Q;
import android.graphics.RenderNode;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
-@Implements(value = RenderNode.class, isInAndroidSdk = false, minSdk = LOLLIPOP)
+@Implements(value = RenderNode.class, isInAndroidSdk = false, minSdk = Q)
public class ShadowRenderNode {
private float alpha = 1f;
private float cameraDistance;
@@ -196,4 +197,10 @@ public class ShadowRenderNode {
public float getPivotY() {
return pivotY;
}
-} \ No newline at end of file
+
+ @Implementation
+ protected boolean isValid() {
+ return true;
+ }
+}
+// END-INTERNAL \ No newline at end of file
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowResolveInfo.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowResolveInfo.java
index 03fb25897..d80fe2338 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowResolveInfo.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowResolveInfo.java
@@ -46,7 +46,7 @@ public class ShadowResolveInfo {
}
@Implementation
- public String loadLabel(PackageManager mgr) {
+ protected CharSequence loadLabel(PackageManager mgr) {
return label;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowResultReceiver.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowResultReceiver.java
index b31fe20c2..6ee4aa0c3 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowResultReceiver.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowResultReceiver.java
@@ -13,7 +13,7 @@ public class ShadowResultReceiver {
@RealObject private ResultReceiver realResultReceiver;
@Implementation
- public void send(int resultCode, android.os.Bundle resultData) {
+ protected void send(int resultCode, android.os.Bundle resultData) {
ReflectionHelpers.callInstanceMethod(realResultReceiver, "onReceiveResult",
ClassParameter.from(Integer.TYPE, resultCode),
ClassParameter.from(Bundle.class, resultData));
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSQLiteOpenHelper.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSQLiteOpenHelper.java
index f04499c3d..8621359d1 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSQLiteOpenHelper.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSQLiteOpenHelper.java
@@ -3,7 +3,6 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.O_MR1;
import android.database.sqlite.SQLiteOpenHelper;
-
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -14,7 +13,7 @@ import org.robolectric.annotation.Implements;
@Implements(SQLiteOpenHelper.class)
public class ShadowSQLiteOpenHelper {
@Implementation(minSdk = O_MR1)
- public void setIdleConnectionTimeout(long idleConnectionTimeoutMs) {
+ protected void setIdleConnectionTimeout(long idleConnectionTimeoutMs) {
// Calling the real one currently results in a Robolectric deadlock. Just ignore it.
// See b/78464547 .
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowScaleGestureDetector.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowScaleGestureDetector.java
index 42ba07245..c7f920551 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowScaleGestureDetector.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowScaleGestureDetector.java
@@ -17,12 +17,13 @@ public class ShadowScaleGestureDetector {
private float focusY;
@Implementation
- public void __constructor__(Context context, ScaleGestureDetector.OnScaleGestureListener listener) {
+ protected void __constructor__(
+ Context context, ScaleGestureDetector.OnScaleGestureListener listener) {
this.listener = listener;
}
@Implementation
- public boolean onTouchEvent(MotionEvent event) {
+ protected boolean onTouchEvent(MotionEvent event) {
onTouchEventMotionEvent = event;
return true;
}
@@ -47,7 +48,7 @@ public class ShadowScaleGestureDetector {
}
@Implementation
- public float getScaleFactor() {
+ protected float getScaleFactor() {
return scaleFactor;
}
@@ -57,12 +58,12 @@ public class ShadowScaleGestureDetector {
}
@Implementation
- public float getFocusX(){
+ protected float getFocusX() {
return focusX;
}
@Implementation
- public float getFocusY(){
+ protected float getFocusY() {
return focusY;
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowScroller.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowScroller.java
index 40edd9dad..2a4e28a57 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowScroller.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowScroller.java
@@ -15,44 +15,44 @@ public class ShadowScroller {
private boolean started;
@Implementation
- public int getStartX() {
+ protected int getStartX() {
return startX;
}
@Implementation
- public int getStartY() {
+ protected int getStartY() {
return startY;
}
@Implementation
- public int getCurrX() {
+ protected int getCurrX() {
long dt = deltaTime();
return dt >= duration ? finalX : startX + (int) ((deltaX() * dt) / duration);
}
@Implementation
- public int getCurrY() {
+ protected int getCurrY() {
long dt = deltaTime();
return dt >= duration ? finalY : startY + (int) ((deltaY() * dt) / duration);
}
@Implementation
- public int getFinalX() {
+ protected int getFinalX() {
return finalX;
}
@Implementation
- public int getFinalY() {
+ protected int getFinalY() {
return finalY;
}
@Implementation
- public int getDuration() {
+ protected int getDuration() {
return (int) duration;
}
@Implementation
- public void startScroll(int startX, int startY, int dx, int dy, int duration) {
+ protected void startScroll(int startX, int startY, int dx, int dy, int duration) {
this.startX = startX;
this.startY = startY;
finalX = startX + dx;
@@ -70,7 +70,7 @@ public class ShadowScroller {
}
@Implementation
- public boolean computeScrollOffset() {
+ protected boolean computeScrollOffset() {
if (!started) {
return false;
}
@@ -79,12 +79,12 @@ public class ShadowScroller {
}
@Implementation
- public boolean isFinished() {
+ protected boolean isFinished() {
return deltaTime() > duration;
}
@Implementation
- public int timePassed() {
+ protected int timePassed() {
return (int) deltaTime();
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSeekBar.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSeekBar.java
index 3279cc4cc..2ca148b54 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSeekBar.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSeekBar.java
@@ -15,7 +15,7 @@ public class ShadowSeekBar extends ShadowAbsSeekBar {
private SeekBar.OnSeekBarChangeListener listener;
@Implementation
- public void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener listener) {
+ protected void setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener listener) {
this.listener = listener;
Shadow.directlyOn(realSeekBar, SeekBar.class).setOnSeekBarChangeListener(listener);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensor.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensor.java
index 43149cb23..c37ca3a3d 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensor.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensor.java
@@ -9,9 +9,6 @@ import org.robolectric.shadow.api.Shadow;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.ReflectionHelpers.ClassParameter;
-/**
- * Shadow for {@link Sensor}.
- */
@Implements(Sensor.class)
public class ShadowSensor {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java
index c51abec08..68a80cd43 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java
@@ -11,7 +11,9 @@ import android.hardware.SensorManager;
import android.os.Handler;
import android.os.MemoryFile;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -47,7 +49,7 @@ public class ShadowSensorManager {
}
@Implementation
- public Sensor getDefaultSensor(int type) {
+ protected Sensor getDefaultSensor(int type) {
return sensorMap.get(type);
}
@@ -59,7 +61,7 @@ public class ShadowSensorManager {
}
@Implementation
- public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) {
+ protected boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) {
if (forceListenersToFail) {
return false;
}
@@ -70,12 +72,12 @@ public class ShadowSensorManager {
}
@Implementation
- public void unregisterListener(SensorEventListener listener, Sensor sensor) {
+ protected void unregisterListener(SensorEventListener listener, Sensor sensor) {
listeners.remove(listener);
}
@Implementation
- public void unregisterListener(SensorEventListener listener) {
+ protected void unregisterListener(SensorEventListener listener) {
listeners.remove(listener);
}
@@ -83,6 +85,14 @@ public class ShadowSensorManager {
return listeners.contains(listener);
}
+ /**
+ * Returns the list of {@link SensorEventListener}s registered on this SensorManager. Note that
+ * the list is unmodifiable, any attempt to modify it will throw an exception.
+ */
+ public List<SensorEventListener> getListeners() {
+ return Collections.unmodifiableList(listeners);
+ }
+
/** Propagates the {@code event} to all registered listeners. */
public void sendSensorEventToListeners(SensorEvent event) {
for (SensorEventListener listener : listeners) {
@@ -113,10 +123,8 @@ public class ShadowSensorManager {
return ReflectionHelpers.callConstructor(SensorEvent.class, valueArraySizeParam);
}
-
-
@Implementation(minSdk = O)
- public Object createDirectChannel(MemoryFile mem) {
+ protected Object createDirectChannel(MemoryFile mem) {
return ReflectionHelpers.callConstructor(SensorDirectChannel.class,
ClassParameter.from(SensorManager.class, realObject),
ClassParameter.from(int.class, 0),
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowService.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowService.java
index 4b2023cd2..440e41c3c 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowService.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowService.java
@@ -21,24 +21,30 @@ public class ShadowService extends ShadowContextWrapper {
private boolean notificationShouldRemoved;
@Implementation
- public void onDestroy() {
+ protected void onDestroy() {
removeForegroundNotification();
}
@Implementation
- public void stopSelf() {
+ protected void stopSelf() {
selfStopped = true;
}
@Implementation
- public void stopSelf(int id) {
+ protected void stopSelf(int id) {
selfStopped = true;
}
@Implementation
- public final void startForeground(int id, Notification notification) {
+ protected boolean stopSelfResult(int id) {
+ selfStopped = true;
+ return true;
+ }
+
+ @Implementation
+ protected final void startForeground(int id, Notification notification) {
foregroundStopped = false;
- lastForegroundNotificationId = id;
+ lastForegroundNotificationId = id;
lastForegroundNotification = notification;
notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
NotificationManager nm = (NotificationManager)RuntimeEnvironment.application.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -46,7 +52,7 @@ public class ShadowService extends ShadowContextWrapper {
}
@Implementation
- public void stopForeground(boolean removeNotification) {
+ protected void stopForeground(boolean removeNotification) {
foregroundStopped = true;
notificationShouldRemoved = removeNotification;
if (removeNotification) {
@@ -56,14 +62,14 @@ public class ShadowService extends ShadowContextWrapper {
private void removeForegroundNotification() {
NotificationManager nm = (NotificationManager)RuntimeEnvironment.application.getSystemService(Context.NOTIFICATION_SERVICE);
- nm.cancel(lastForegroundNotificationId);
+ nm.cancel(lastForegroundNotificationId);
lastForegroundNotification = null;
}
-
+
public int getLastForegroundNotificationId() {
return lastForegroundNotificationId;
}
-
+
public Notification getLastForegroundNotification() {
return lastForegroundNotification;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java
index 3a6b13311..792bd28d8 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java
@@ -8,6 +8,7 @@ import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.N_MR1;
import static android.os.Build.VERSION_CODES.O;
import static android.os.Build.VERSION_CODES.Q;
+import static android.os.Build.VERSION_CODES.P;
import android.accounts.IAccountManager;
import android.app.IAlarmManager;
@@ -15,6 +16,7 @@ import android.app.INotificationManager;
import android.app.ISearchManager;
import android.app.admin.IDevicePolicyManager;
import android.app.job.IJobScheduler;
+import android.app.slice.ISliceManager;
import android.app.trust.ITrustManager;
import android.app.usage.IUsageStatsManager;
import android.content.Context;
@@ -177,6 +179,11 @@ public class ShadowServiceManager {
createBinder(
"android.os.storage.IMountService", "android.os.storage.IMountService"));
}
+ if (RuntimeEnvironment.getApiLevel() >= P) {
+ put(
+ Context.SLICE_SERVICE,
+ createBinder(ISliceManager.class, "android.app.slice.SliceManager"));
+ }
// BEGIN-INTERNAL
if (RuntimeEnvironment.getApiLevel() >= Q) {
put(Context.NOTIFICATION_SERVICE,
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java
index 759dbabfe..7b1adeeef 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java
@@ -62,9 +62,6 @@ public class ShadowSettings {
}
}
- /**
- * Shadow for {@link Settings.Secure}
- */
@Implements(value = Settings.Secure.class)
public static class ShadowSecure {
private static final Map<ContentResolver, Map<String, String>> dataMap = new WeakHashMap<>();
@@ -192,9 +189,6 @@ public class ShadowSettings {
}
}
- /**
- * Shadow for {@link Settings.Global}
- */
@Implements(value = Settings.Global.class, minSdk = JELLY_BEAN_MR1)
public static class ShadowGlobal {
private static final Map<ContentResolver, Map<String, String>> dataMap = new WeakHashMap<>();
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSharedPreferences.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSharedPreferences.java
new file mode 100644
index 000000000..e0404476d
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSharedPreferences.java
@@ -0,0 +1,28 @@
+package org.robolectric.shadows;
+
+import android.app.QueuedWork;
+import android.os.Build.VERSION_CODES;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.shadow.api.Shadow;
+
+/** Dummy container class for nested shadow class */
+public class ShadowSharedPreferences {
+
+ @Implements(
+ className = "android.app.SharedPreferencesImpl$EditorImpl",
+ minSdk = VERSION_CODES.O,
+ isInAndroidSdk = false)
+ public static class ShadowSharedPreferencesEditorImpl {
+
+ @RealObject Object realObject;
+
+ @Implementation
+ protected void apply() {
+ Shadow.directlyOn(realObject, "android.app.SharedPreferencesImpl$EditorImpl", "apply");
+ // Flush QueuedWork. This resolves the deadlock of calling 'apply' followed by 'commit'.
+ QueuedWork.waitToFinish();
+ }
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSliceManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSliceManager.java
new file mode 100644
index 000000000..e75a8799a
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSliceManager.java
@@ -0,0 +1,80 @@
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.P;
+
+import android.app.slice.SliceManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.os.Handler;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+/** Shadow of {@link SliceManager}. */
+@Implements(value = SliceManager.class, minSdk = P)
+public class ShadowSliceManager {
+
+ private static final Map<Integer, Collection<Uri>> packageUidsToPermissionGrantedSliceUris =
+ new HashMap<>();
+ private Context context;
+
+ @Implementation
+ protected void __constructor__(Context context, Handler handler) {
+ this.context = context;
+ }
+
+ @Implementation
+ protected synchronized void grantSlicePermission(String toPackage, Uri uri) {
+ int packageUid = getUidForPackage(toPackage);
+ Collection<Uri> uris = packageUidsToPermissionGrantedSliceUris.get(packageUid);
+ if (uris == null) {
+ uris = new ArrayList<>();
+ packageUidsToPermissionGrantedSliceUris.put(packageUid, uris);
+ }
+ uris.add(uri);
+ }
+
+ @Implementation
+ protected synchronized void revokeSlicePermission(String toPackage, Uri uri) {
+ int packageUid = getUidForPackage(toPackage);
+ Collection<Uri> uris = packageUidsToPermissionGrantedSliceUris.get(packageUid);
+ if (uris != null) {
+ uris.remove(uri);
+ if (uris.isEmpty()) {
+ packageUidsToPermissionGrantedSliceUris.remove(packageUid);
+ }
+ }
+ }
+
+ @Implementation
+ protected synchronized int checkSlicePermission(Uri uri, int pid, int uid) {
+ if (uid == 0) {
+ return PackageManager.PERMISSION_GRANTED;
+ }
+ Collection<Uri> uris = packageUidsToPermissionGrantedSliceUris.get(uid);
+ if (uris != null && uris.contains(uri)) {
+ return PackageManager.PERMISSION_GRANTED;
+ }
+ return PackageManager.PERMISSION_DENIED;
+ }
+
+ private int getUidForPackage(String packageName) {
+ PackageManager packageManager = context.getPackageManager();
+ try {
+ return packageManager.getPackageUid(packageName, 0);
+ } catch (NameNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Resetter
+ public static synchronized void reset() {
+ packageUidsToPermissionGrantedSliceUris.clear();
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSmsManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSmsManager.java
index aabcbf2b1..1fca7deaf 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSmsManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSmsManager.java
@@ -6,33 +6,25 @@ import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
import android.app.PendingIntent;
import android.telephony.SmsManager;
import android.text.TextUtils;
-import android.util.SparseArray;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
-import org.robolectric.shadow.api.Shadow;
+import org.robolectric.annotation.Resetter;
+import org.robolectric.util.ReflectionHelpers;
@Implements(value = SmsManager.class, minSdk = JELLY_BEAN_MR2)
public class ShadowSmsManager {
- private static final SmsManager realManager = Shadow.newInstanceOf(SmsManager.class);
- private static final SparseArray<SmsManager> subSmsManagers = new SparseArray<>(1);
-
- @Implementation
- public static SmsManager getDefault() {
- return realManager;
- }
-
- @Implementation(minSdk = LOLLIPOP_MR1)
- public static SmsManager getSmsManagerForSubscriptionId(int subId) {
- SmsManager smsManager = subSmsManagers.get(subId);
- if (smsManager == null) {
- smsManager =
- Shadow.newInstance(SmsManager.class, new Class[] {int.class}, new Object[] {subId});
- subSmsManagers.put(subId, smsManager);
+ @Resetter
+ public static void reset() {
+ if (RuntimeEnvironment.getApiLevel() >= LOLLIPOP_MR1) {
+ Map<String, Object> sSubInstances =
+ ReflectionHelpers.getStaticField(SmsManager.class, "sSubInstances");
+ sSubInstances.clear();
}
- return smsManager;
}
private TextSmsParams lastTextSmsParams;
@@ -40,7 +32,13 @@ public class ShadowSmsManager {
private DataMessageParams lastDataParams;
@Implementation
- public void sendDataMessage(String destinationAddress, String scAddress, short destinationPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ protected void sendDataMessage(
+ String destinationAddress,
+ String scAddress,
+ short destinationPort,
+ byte[] data,
+ PendingIntent sentIntent,
+ PendingIntent deliveryIntent) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
@@ -49,7 +47,12 @@ public class ShadowSmsManager {
}
@Implementation
- public void sendTextMessage(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ protected void sendTextMessage(
+ String destinationAddress,
+ String scAddress,
+ String text,
+ PendingIntent sentIntent,
+ PendingIntent deliveryIntent) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
@@ -62,7 +65,12 @@ public class ShadowSmsManager {
}
@Implementation
- public void sendMultipartTextMessage(String destinationAddress, String scAddress, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
+ protected void sendMultipartTextMessage(
+ String destinationAddress,
+ String scAddress,
+ ArrayList<String> parts,
+ ArrayList<PendingIntent> sentIntents,
+ ArrayList<PendingIntent> deliveryIntents) {
if (TextUtils.isEmpty(destinationAddress)) {
throw new IllegalArgumentException("Invalid destinationAddress");
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSoundPool.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSoundPool.java
index f5da20b0b..3bc0eac9c 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSoundPool.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSoundPool.java
@@ -8,10 +8,14 @@ import static android.os.Build.VERSION_CODES.N_MR1;
import android.content.Context;
import android.media.IAudioService;
import android.media.SoundPool;
+import android.media.SoundPool.OnLoadCompleteListener;
import android.util.SparseArray;
import android.util.SparseIntArray;
+import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -20,8 +24,7 @@ import org.robolectric.util.ReflectionHelpers;
@Implements(SoundPool.class)
public class ShadowSoundPool {
- @RealObject
- SoundPool realObject;
+ @RealObject SoundPool realObject;
/** Generates sound ids when they are loaded. */
private final AtomicInteger soundIds = new AtomicInteger();
@@ -32,7 +35,9 @@ public class ShadowSoundPool {
/** Tracks mapping between sound ids and the resource id they refer too. */
private final SparseIntArray idToRes = new SparseIntArray();
- private final List<Integer> playedSounds = new ArrayList<>();
+ private final List<Playback> playedSounds = new ArrayList<>();
+
+ private OnLoadCompleteListener listener;
@Implementation(minSdk = N, maxSdk = N_MR1)
protected static IAudioService getService() {
@@ -45,14 +50,14 @@ public class ShadowSoundPool {
@Implementation(maxSdk = LOLLIPOP_MR1)
protected int play(
int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate) {
- playedSounds.add(soundID);
+ playedSounds.add(new Playback(soundID, leftVolume, rightVolume, priority, loop, rate));
return 1;
}
@Implementation(minSdk = M)
protected int _play(
int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate) {
- playedSounds.add(soundID);
+ playedSounds.add(new Playback(soundID, leftVolume, rightVolume, priority, loop, rate));
return 1;
}
@@ -72,10 +77,47 @@ public class ShadowSoundPool {
return soundId;
}
+ @Implementation
+ protected void setOnLoadCompleteListener(OnLoadCompleteListener listener) {
+ this.listener = listener;
+ }
+
+ /** Notify the {@link OnLoadCompleteListener}, if present, that the given path was loaded. */
+ public void notifyPathLoaded(String path, boolean success) {
+ boolean soundIsKnown = false;
+ for (int pathIdx = 0; pathIdx < idToPaths.size(); ++pathIdx) {
+ if (idToPaths.valueAt(pathIdx).equals(path)) {
+ if (listener != null) {
+ listener.onLoadComplete(realObject, idToPaths.keyAt(pathIdx), success ? 0 : 1);
+ }
+ soundIsKnown = true;
+ }
+ }
+ if (!soundIsKnown) {
+ throw new IllegalArgumentException("Unknown sound. You need to call load() first");
+ }
+ }
+
+ /** Notify the {@link OnLoadCompleteListener}, if present, that the given resource was loaded. */
+ public void notifyResourceLoaded(int resId, boolean success) {
+ boolean soundIsKnown = false;
+ for (int resIdx = 0; resIdx < idToRes.size(); ++resIdx) {
+ if (idToRes.valueAt(resIdx) == resId) {
+ if (listener != null) {
+ listener.onLoadComplete(realObject, idToRes.keyAt(resIdx), success ? 0 : 1);
+ }
+ soundIsKnown = true;
+ }
+ }
+ if (!soundIsKnown) {
+ throw new IllegalArgumentException("Unknown sound. You need to call load() first");
+ }
+ }
+
/** Returns {@code true} if the given path was played. */
public boolean wasPathPlayed(String path) {
- for (int id : playedSounds) {
- if (idToPaths.indexOfKey(id) >= 0 && idToPaths.get(id).equals(path)) {
+ for (Playback playback : playedSounds) {
+ if (idIsForPath(playback.soundId, path)) {
return true;
}
}
@@ -84,16 +126,90 @@ public class ShadowSoundPool {
/** Returns {@code true} if the given resource was played. */
public boolean wasResourcePlayed(int resId) {
- for (int id : playedSounds) {
- if (idToRes.indexOfKey(id) >= 0 && idToRes.get(id) == resId) {
+ for (Playback playback : playedSounds) {
+ if (idIsForResource(playback.soundId, resId)) {
return true;
}
}
return false;
}
+ /** Return a list of calls to {@code play} made for the given path. */
+ public List<Playback> getPathPlaybacks(String path) {
+ ImmutableList.Builder<Playback> playbacks = ImmutableList.builder();
+ for (Playback playback : playedSounds) {
+ if (idIsForPath(playback.soundId, path)) {
+ playbacks.add(playback);
+ }
+ }
+ return playbacks.build();
+ }
+
+ /** Return a list of calls to {@code play} made for the given resource. */
+ public List<Playback> getResourcePlaybacks(int resId) {
+ ImmutableList.Builder<Playback> playbacks = ImmutableList.builder();
+ for (Playback playback : playedSounds) {
+ if (idIsForResource(playback.soundId, resId)) {
+ playbacks.add(playback);
+ }
+ }
+ return playbacks.build();
+ }
+
+ private boolean idIsForPath(int soundId, String path) {
+ return idToPaths.indexOfKey(soundId) >= 0 && idToPaths.get(soundId).equals(path);
+ }
+
+ private boolean idIsForResource(int soundId, int resId) {
+ return idToRes.indexOfKey(soundId) >= 0 && idToRes.get(soundId) == resId;
+ }
+
/** Clears the sounds played by this SoundPool. */
public void clearPlayed() {
playedSounds.clear();
}
+
+ /** Record of a single call to {@link SoundPool#play }. */
+ public static final class Playback {
+ public final int soundId;
+ public final float leftVolume;
+ public final float rightVolume;
+ public final int priority;
+ public final int loop;
+ public final float rate;
+
+ public Playback(
+ int soundId, float leftVolume, float rightVolume, int priority, int loop, float rate) {
+ this.soundId = soundId;
+ this.leftVolume = leftVolume;
+ this.rightVolume = rightVolume;
+ this.priority = priority;
+ this.loop = loop;
+ this.rate = rate;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof Playback)) {
+ return false;
+ }
+ Playback that = (Playback) o;
+ return this.soundId == that.soundId
+ && this.leftVolume == that.leftVolume
+ && this.rightVolume == that.rightVolume
+ && this.priority == that.priority
+ && this.loop == that.loop
+ && this.rate == that.rate;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(soundId, leftVolume, rightVolume, priority, loop, rate);
+ }
+
+ @Override
+ public String toString() {
+ return Arrays.asList(soundId, leftVolume, rightVolume, priority, loop, rate).toString();
+ }
+ }
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSslErrorHandler.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSslErrorHandler.java
index c8ab6ab9c..4e9e19669 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSslErrorHandler.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSslErrorHandler.java
@@ -11,7 +11,7 @@ public class ShadowSslErrorHandler extends ShadowHandler {
private boolean proceedCalled = false;
@Implementation
- public void cancel() {
+ protected void cancel() {
cancelCalled = true;
}
@@ -20,7 +20,7 @@ public class ShadowSslErrorHandler extends ShadowHandler {
}
@Implementation
- public void proceed() {
+ protected void proceed() {
proceedCalled = true;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStatFs.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStatFs.java
index 7dfd34875..c066753a1 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStatFs.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStatFs.java
@@ -24,51 +24,52 @@ public class ShadowStatFs {
private Stats stat;
@Implementation
- public void __constructor__(String path) {
+ protected void __constructor__(String path) {
restat(path);
}
@Implementation
- public int getBlockSize() {
+ protected int getBlockSize() {
return BLOCK_SIZE;
}
@Implementation
- public int getBlockCount() {
+ protected int getBlockCount() {
return stat.blockCount;
}
@Implementation
- public int getFreeBlocks() {
+ protected int getFreeBlocks() {
return stat.freeBlocks;
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public long getFreeBlocksLong() {
+ protected long getFreeBlocksLong() {
return stat.freeBlocks;
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public long getFreeBytes() {
+ protected long getFreeBytes() {
return getBlockSizeLong() * getFreeBlocksLong();
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public long getAvailableBytes() {
+ protected long getAvailableBytes() {
return getBlockSizeLong() * getAvailableBlocksLong();
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public long getTotalBytes() {
+ protected long getTotalBytes() {
return getBlockSizeLong() * getBlockCountLong();
}
+
@Implementation
- public int getAvailableBlocks() {
+ protected int getAvailableBlocks() {
return stat.availableBlocks;
}
@Implementation
- public void restat(String path) {
+ protected void restat(String path) {
Map.Entry<String, Stats> mapEntry = stats.floorEntry(path);
for (;;) {
// We will hit all matching paths, longest one first. We may hit non-matching paths before we
@@ -86,21 +87,19 @@ public class ShadowStatFs {
}
}
- /**
- * Robolectric always uses a block size of `4096`.
- */
+ /** Robolectric always uses a block size of `4096`. */
@Implementation(minSdk = JELLY_BEAN_MR2)
- public long getBlockSizeLong() {
+ protected long getBlockSizeLong() {
return BLOCK_SIZE;
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public long getBlockCountLong() {
+ protected long getBlockCountLong() {
return stat.blockCount;
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public long getAvailableBlocksLong() {
+ protected long getAvailableBlocksLong() {
return stat.availableBlocks;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStateListDrawable.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStateListDrawable.java
index fca23b1bc..4e387d942 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStateListDrawable.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStateListDrawable.java
@@ -24,7 +24,7 @@ public class ShadowStateListDrawable extends ShadowDrawable {
}
@Implementation
- public void addState(int[] stateSet, Drawable drawable) {
+ protected void addState(int[] stateSet, Drawable drawable) {
stateToDrawable.put(createStateList(stateSet), drawable);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStatusBarManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStatusBarManager.java
new file mode 100644
index 000000000..9b58618a1
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStatusBarManager.java
@@ -0,0 +1,37 @@
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.M;
+
+import android.app.StatusBarManager;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/** Robolectric implementation of {@link android.app.StatusBarManager}. */
+@Implements(value = StatusBarManager.class, isInAndroidSdk = false)
+public class ShadowStatusBarManager {
+
+ public static final int DEFAULT_DISABLE_MASK = StatusBarManager.DISABLE_MASK;
+ public static final int DEFAULT_DISABLE2_MASK = StatusBarManager.DISABLE2_MASK;
+ private int disabled = StatusBarManager.DISABLE_NONE;
+ private int disabled2 = StatusBarManager.DISABLE2_NONE;
+
+ @Implementation
+ protected void disable(int what) {
+ disabled = what;
+ }
+
+ @Implementation(minSdk = M)
+ protected void disable2(int what) {
+ disabled2 = what;
+ }
+
+ /** Returns the disable flags previously set in {@link #disable}. */
+ public int getDisableFlags() {
+ return disabled;
+ }
+
+ /** Returns the disable flags previously set in {@link #disable2}. */
+ public int getDisable2Flags() {
+ return disabled2;
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStorageManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStorageManager.java
index c53d3bfd3..2614d7e88 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStorageManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStorageManager.java
@@ -3,14 +3,18 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.N;
import static org.robolectric.RuntimeEnvironment.application;
-import static org.robolectric.Shadows.shadowOf;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
+import com.google.common.base.Preconditions;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.robolectric.shadow.api.Shadow;
/**
* Fake implementation of {@link android.os.storage.StorageManager}
@@ -19,6 +23,7 @@ import org.robolectric.annotation.Implements;
public class ShadowStorageManager {
private static boolean isFileEncryptionSupported = true;
+ private final List<StorageVolume> storageVolumeList = new ArrayList<>();
@Implementation(minSdk = M)
protected static StorageVolume[] getVolumeList(int userId, int flags) {
@@ -34,6 +39,49 @@ public class ShadowStorageManager {
return getVolumeList(0, 0);
}
+ /**
+ * Adds a {@link StorageVolume} to the list returned by {@link #getStorageVolumes()}.
+ *
+ * @param StorageVolume to add to list
+ */
+ public void addStorageVolume(StorageVolume storageVolume) {
+ Preconditions.checkNotNull(storageVolume);
+ storageVolumeList.add(storageVolume);
+ }
+
+ /**
+ * Returns the storage volumes configured via {@link #addStorageVolume()}.
+ *
+ * @return StorageVolume list
+ */
+ @Implementation(minSdk = N)
+ protected List<StorageVolume> getStorageVolumes() {
+ return storageVolumeList;
+ }
+
+ /** Clears the storageVolumeList. */
+ public void resetStorageVolumeList() {
+ storageVolumeList.clear();
+ }
+
+ /**
+ * Checks whether File belongs to any {@link StorageVolume} in the list returned by {@link
+ * #getStorageVolumes()}.
+ *
+ * @param File to check
+ * @return StorageVolume for the file
+ */
+ @Implementation(minSdk = N)
+ public StorageVolume getStorageVolume(File file) {
+ for (StorageVolume volume : storageVolumeList) {
+ File volumeFile = volume.getPathFile();
+ if (file.getAbsolutePath().equals(volumeFile.getAbsolutePath())) {
+ return volume;
+ }
+ }
+ return null;
+ }
+
@HiddenApi
@Implementation(minSdk = N)
protected static boolean isFileEncryptedNativeOrEmulated() {
@@ -52,6 +100,7 @@ public class ShadowStorageManager {
@HiddenApi
@Implementation(minSdk = N)
protected static boolean isUserKeyUnlocked(int userId) {
- return shadowOf(application.getSystemService(UserManager.class)).isUserUnlocked();
+ ShadowUserManager extract = Shadow.extract(application.getSystemService(UserManager.class));
+ return extract.isUserUnlocked();
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStrictModeVmPolicy.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStrictModeVmPolicy.java
index 51a931a22..32e7be58a 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStrictModeVmPolicy.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStrictModeVmPolicy.java
@@ -8,7 +8,6 @@ import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.util.ReflectionHelpers;
-/** Shadow for StrictMode.VmPolicy */
@Implements(value=StrictMode.VmPolicy.class, minSdk = Build.VERSION_CODES.P)
public class ShadowStrictModeVmPolicy {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSubscriptionManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSubscriptionManager.java
index ae949cbbb..24d041516 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSubscriptionManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSubscriptionManager.java
@@ -1,61 +1,57 @@
package org.robolectric.shadows;
+import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1;
import static android.os.Build.VERSION_CODES.N;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;
+import org.robolectric.util.ReflectionHelpers;
-/**
- * Shadow for {@link SubscriptionManager}.
- *
- * <p>Although {@link SubscriptionManager} itself has been added in LMR1, this shadow is only
- * available since N because all shadowed methods have been added in N.
- */
-@Implements(value = SubscriptionManager.class, minSdk = N)
+@Implements(value = SubscriptionManager.class, minSdk = LOLLIPOP_MR1)
public class ShadowSubscriptionManager {
+ private static int defaultSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private static int defaultDataSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private static int defaultSmsSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private static int defaultVoiceSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- private static int defaultSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
- private List<SubscriptionInfo> mSubscriptionInfoList;
- @Implementation
- public List<SubscriptionInfo> getActiveSubscriptionInfoList() {
- return mSubscriptionInfoList;
- }
-
- public void setActiveSubscriptionInfoList(List<SubscriptionInfo> subscriptionInfoList) {
- mSubscriptionInfoList = subscriptionInfoList;
+ /** Returns value set with {@link #setDefaultSubscriptionId(int)}. */
+ @Implementation(minSdk = N)
+ protected static int getDefaultSubscriptionId() {
+ return defaultSubscriptionId;
}
/** Returns value set with {@link #setDefaultDataSubscriptionId(int)}. */
- @Implementation
+ @Implementation(minSdk = N)
protected static int getDefaultDataSubscriptionId() {
return defaultDataSubscriptionId;
}
/** Returns value set with {@link #setDefaultSmsSubscriptionId(int)}. */
- @Implementation
+ @Implementation(minSdk = N)
protected static int getDefaultSmsSubscriptionId() {
return defaultSmsSubscriptionId;
}
/** Returns value set with {@link #setDefaultVoiceSubscriptionId(int)}. */
- @Implementation
+ @Implementation(minSdk = N)
protected static int getDefaultVoiceSubscriptionId() {
return defaultVoiceSubscriptionId;
}
- /** Returns value set with {@link #setDefaultSubscriptionId(int)}. */
- @Implementation
- public static int getDefaultSubscriptionId() {
- return defaultSubscriptionId;
+ /** Sets the value that will be returned by {@link #getDefaultSubscriptionId()}. */
+ public static void setDefaultSubscriptionId(int defaultDataSubscriptionId) {
+ ShadowSubscriptionManager.defaultSubscriptionId = defaultDataSubscriptionId;
}
public static void setDefaultDataSubscriptionId(int defaultDataSubscriptionId) {
@@ -70,8 +66,165 @@ public class ShadowSubscriptionManager {
ShadowSubscriptionManager.defaultVoiceSubscriptionId = defaultVoiceSubscriptionId;
}
- public static void setDefaultSubscriptionId(int defaultSubscriptionId) {
- ShadowSubscriptionManager.defaultSubscriptionId = defaultSubscriptionId;
+ /**
+ * Cache of {@link SubscriptionInfo} used by {@link #getActiveSubscriptionInfoList}.
+ * Managed by {@link #setActiveSubscriptionInfoList}.
+ */
+ private List<SubscriptionInfo> subscriptionList = new ArrayList<>();
+ /**
+ * List of listeners to be notified if the list of {@link SubscriptionInfo} changes. Managed by
+ * {@link #addOnSubscriptionsChangedListener} and {@link removeOnSubscriptionsChangedListener}.
+ */
+ private List<OnSubscriptionsChangedListener> listeners = new ArrayList<>();
+ /**
+ * Cache of subscription ids used by {@link #isNetworkRoaming}. Managed by {@link
+ * #setNetworkRoamingStatus} and {@link #clearNetworkRoamingStatus}.
+ */
+ private Set<Integer> roamingSimSubscriptionIds = new HashSet<>();
+
+ /**
+ * Returns the active list of {@link SubscriptionInfo} that were set via {@link
+ * #setActiveSubscriptionInfoList}.
+ */
+ @Implementation(minSdk = LOLLIPOP_MR1)
+ protected List<SubscriptionInfo> getActiveSubscriptionInfoList() {
+ return subscriptionList;
+ }
+
+ /**
+ * Returns the size of the list of {@link SubscriptionInfo} that were set via {@link
+ * #setActiveSubscriptionInfoList}. If no list was set, returns 0.
+ */
+ @Implementation(minSdk = LOLLIPOP_MR1)
+ protected int getActiveSubscriptionInfoCount() {
+ return subscriptionList == null ? 0 : subscriptionList.size();
+ }
+
+ /**
+ * Returns subscription that were set via {@link #setActiveSubscriptionInfoList} if it can find
+ * one with the specified id or null if none found.
+ */
+ @Implementation(minSdk = LOLLIPOP_MR1)
+ protected SubscriptionInfo getActiveSubscriptionInfo(int subId) {
+ if (subscriptionList == null) {
+ return null;
+ }
+ for (SubscriptionInfo info : subscriptionList) {
+ if (info.getSubscriptionId() == subId) {
+ return info;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns subscription that were set via {@link #setActiveSubscriptionInfoList} if it can find
+ * one with the specified slot index or null if none found.
+ */
+ @Implementation(minSdk = N)
+ protected SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex) {
+ if (subscriptionList == null) {
+ return null;
+ }
+ for (SubscriptionInfo info : subscriptionList) {
+ if (info.getSimSlotIndex() == slotIndex) {
+ return info;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Sets the active list of {@link SubscriptionInfo}. This call internally triggers {@link
+ * OnSubscriptionsChangedListener#onSubscriptionsChanged()} to all the listeners.
+ * @param list - The subscription info list, can be null.
+ */
+ public void setActiveSubscriptionInfoList(List<SubscriptionInfo> list) {
+ subscriptionList = list;
+ dispatchOnSubscriptionsChanged();
+ }
+
+ /**
+ * Sets the active list of {@link SubscriptionInfo}. This call internally triggers {@link
+ * OnSubscriptionsChangedListener#onSubscriptionsChanged()} to all the listeners.
+ */
+ public void setActiveSubscriptionInfos(SubscriptionInfo... infos) {
+ if (infos == null) {
+ setActiveSubscriptionInfoList(null);
+ } else {
+ setActiveSubscriptionInfoList(Arrays.asList(infos));
+ }
+ }
+
+ /**
+ * Adds a listener to a local list of listeners. Will be triggered by {@link
+ * #setActiveSubscriptionInfoList} when the local list of {@link SubscriptionInfo} is updated.
+ */
+ @Implementation(minSdk = LOLLIPOP_MR1)
+ protected void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
+ listeners.add(listener);
+ }
+
+ /**
+ * Removes a listener from a local list of listeners. Will be triggered by {@link
+ * #setActiveSubscriptionInfoList} when the local list of {@link SubscriptionInfo} is updated.
+ */
+ @Implementation(minSdk = LOLLIPOP_MR1)
+ protected void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
+ listeners.remove(listener);
+ }
+
+ /** Returns subscription Ids that were set via {@link #setActiveSubscriptionInfoList}. */
+ @Implementation(minSdk = LOLLIPOP_MR1)
+ @HiddenApi
+ protected int[] getActiveSubscriptionIdList() {
+ final List<SubscriptionInfo> infos = getActiveSubscriptionInfoList();
+ if (infos == null) {
+ return new int[0];
+ }
+ int[] ids = new int[infos.size()];
+ for (int i = 0; i < infos.size(); i++) {
+ ids[i] = infos.get(i).getSubscriptionId();
+ }
+ return ids;
+ }
+
+ /**
+ * Notifies {@link OnSubscriptionsChangedListener} listeners that the list of {@link
+ * SubscriptionInfo} has been updated.
+ */
+ private void dispatchOnSubscriptionsChanged() {
+ for (OnSubscriptionsChangedListener listener : listeners) {
+ listener.onSubscriptionsChanged();
+ }
+ }
+
+ /** Clears the local cache of roaming subscription Ids used by {@link #isNetworkRoaming}. */
+ public void clearNetworkRoamingStatus(){
+ roamingSimSubscriptionIds.clear();
+ }
+
+ /**
+ * If isNetworkRoaming is set, it will mark the provided sim subscriptionId as roaming in a local
+ * cache. If isNetworkRoaming is unset it will remove the subscriptionId from the local cache. The
+ * local cache is used to provide roaming status returned by {@link #isNetworkRoaming}.
+ */
+ public void setNetworkRoamingStatus(int simSubscriptionId, boolean isNetworkRoaming) {
+ if (isNetworkRoaming) {
+ roamingSimSubscriptionIds.add(simSubscriptionId);
+ } else {
+ roamingSimSubscriptionIds.remove(simSubscriptionId);
+ }
+ }
+
+ /**
+ * Uses the local cache of roaming sim subscription Ids managed by {@link
+ * #setNetworkRoamingStatus} to return subscription Ids marked as roaming. Otherwise subscription
+ * Ids will be considered as non-roaming if they are not in the cache.
+ */
+ @Implementation(minSdk = LOLLIPOP_MR1)
+ protected boolean isNetworkRoaming(int simSubscriptionId) {
+ return roamingSimSubscriptionIds.contains(simSubscriptionId);
}
@Resetter
@@ -81,4 +234,66 @@ public class ShadowSubscriptionManager {
defaultVoiceSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
defaultSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
+
+ /** Builder class to create instance of {@link SubscriptionInfo}. */
+ public static class SubscriptionInfoBuilder {
+ private final SubscriptionInfo subscriptionInfo =
+ ReflectionHelpers.callConstructor(SubscriptionInfo.class);
+
+ public static SubscriptionInfoBuilder newBuilder() {
+ return new SubscriptionInfoBuilder();
+ }
+
+ public SubscriptionInfo buildSubscriptionInfo() {
+ return subscriptionInfo;
+ }
+
+ public SubscriptionInfoBuilder setId(int id) {
+ ReflectionHelpers.setField(subscriptionInfo, "mId", id);
+ return this;
+ }
+
+ public SubscriptionInfoBuilder setIccId(String iccId) {
+ ReflectionHelpers.setField(subscriptionInfo, "mIccId", iccId);
+ return this;
+ }
+
+ public SubscriptionInfoBuilder setSimSlotIndex(int index) {
+ ReflectionHelpers.setField(subscriptionInfo, "mSimSlotIndex", index);
+ return this;
+ }
+
+ public SubscriptionInfoBuilder setDisplayName(String name) {
+ ReflectionHelpers.setField(subscriptionInfo, "mDisplayName", name);
+ return this;
+ }
+
+ public SubscriptionInfoBuilder setCarrierName(String carrierName) {
+ ReflectionHelpers.setField(subscriptionInfo, "mCarrierName", carrierName);
+ return this;
+ }
+
+ public SubscriptionInfoBuilder setIconTint(int iconTint) {
+ ReflectionHelpers.setField(subscriptionInfo, "mIconTint", iconTint);
+ return this;
+ }
+
+ public SubscriptionInfoBuilder setNumber(String number) {
+ ReflectionHelpers.setField(subscriptionInfo, "mNumber", number);
+ return this;
+ }
+
+ public SubscriptionInfoBuilder setDataRoaming(int dataRoaming) {
+ ReflectionHelpers.setField(subscriptionInfo, "mDataRoaming", dataRoaming);
+ return this;
+ }
+
+ public SubscriptionInfoBuilder setCountryIso(String countryIso) {
+ ReflectionHelpers.setField(subscriptionInfo, "mCountryIso", countryIso);
+ return this;
+ }
+
+ // Use {@link #newBuilder} to construct builders.
+ private SubscriptionInfoBuilder() {}
+ }
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSurface.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSurface.java
index 0c86799b9..1e9597e6e 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSurface.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSurface.java
@@ -14,7 +14,7 @@ public class ShadowSurface {
@RealObject private Surface realSurface;
@Implementation
- public void __constructor__(SurfaceTexture surfaceTexture) {
+ protected void __constructor__(SurfaceTexture surfaceTexture) {
this.surfaceTexture = surfaceTexture;
Shadow.invokeConstructor(
Surface.class, realSurface, ClassParameter.from(SurfaceTexture.class, surfaceTexture));
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSurfaceView.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSurfaceView.java
index 99bafe6e5..7a258dad8 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSurfaceView.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSurfaceView.java
@@ -16,11 +16,10 @@ public class ShadowSurfaceView extends ShadowView {
private final FakeSurfaceHolder fakeSurfaceHolder = new FakeSurfaceHolder();
@Implementation
- public void onAttachedToWindow() {
- }
+ protected void onAttachedToWindow() {}
@Implementation
- public SurfaceHolder getHolder() {
+ protected SurfaceHolder getHolder() {
return fakeSurfaceHolder;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemClock.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemClock.java
index 7c7dbdac4..6c42c05dd 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemClock.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemClock.java
@@ -1,5 +1,6 @@
package org.robolectric.shadows;
+import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static android.os.Build.VERSION_CODES.P;
import android.os.SystemClock;
@@ -29,7 +30,7 @@ public class ShadowSystemClock {
}
@Implementation
- public static void sleep(long millis) {
+ protected static void sleep(long millis) {
if (ShadowApplication.getInstance() == null) {
return;
}
@@ -39,7 +40,7 @@ public class ShadowSystemClock {
}
@Implementation
- public static boolean setCurrentTimeMillis(long millis) {
+ protected static boolean setCurrentTimeMillis(long millis) {
if (ShadowApplication.getInstance() == null) {
return false;
}
@@ -53,17 +54,22 @@ public class ShadowSystemClock {
}
@Implementation
- public static long uptimeMillis() {
+ protected static long uptimeMillis() {
return now() - bootedAt;
}
@Implementation
- public static long elapsedRealtime() {
+ protected static long elapsedRealtime() {
return uptimeMillis();
}
+ @Implementation(minSdk = JELLY_BEAN_MR1)
+ protected static long elapsedRealtimeNanos() {
+ return elapsedRealtime() * MILLIS_PER_NANO;
+ }
+
@Implementation
- public static long currentThreadTimeMillis() {
+ protected static long currentThreadTimeMillis() {
return uptimeMillis();
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTabActivity.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTabActivity.java
index 5bec4db81..d6d0e849f 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTabActivity.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTabActivity.java
@@ -14,7 +14,7 @@ public class ShadowTabActivity extends ShadowActivityGroup {
private TabHost tabhost;
@Implementation
- public TabHost getTabHost() {
+ protected TabHost getTabHost() {
if (tabhost==null) {
tabhost = new TabHost(realTabActivity);
}
@@ -22,7 +22,7 @@ public class ShadowTabActivity extends ShadowActivityGroup {
}
@Implementation
- public TabWidget getTabWidget() {
+ protected TabWidget getTabWidget() {
return getTabHost().getTabWidget();
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTabHost.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTabHost.java
index 0cf6eec80..bc8248162 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTabHost.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTabHost.java
@@ -27,7 +27,7 @@ public class ShadowTabHost extends ShadowViewGroup {
private TabHost realObject;
@Implementation
- public android.widget.TabHost.TabSpec newTabSpec(java.lang.String tag) {
+ protected android.widget.TabHost.TabSpec newTabSpec(java.lang.String tag) {
TabSpec realTabSpec = Shadow.newInstanceOf(TabHost.TabSpec.class);
ShadowTabSpec shadowTabSpec = Shadow.extract(realTabSpec);
shadowTabSpec.setTag(tag);
@@ -35,7 +35,7 @@ public class ShadowTabHost extends ShadowViewGroup {
}
@Implementation
- public void addTab(android.widget.TabHost.TabSpec tabSpec) {
+ protected void addTab(android.widget.TabHost.TabSpec tabSpec) {
tabSpecs.add(tabSpec);
ShadowTabSpec shadowTabSpec = Shadow.extract(tabSpec);
View indicatorAsView = shadowTabSpec.getIndicatorAsView();
@@ -45,7 +45,7 @@ public class ShadowTabHost extends ShadowViewGroup {
}
@Implementation
- public void setCurrentTab(int index) {
+ protected void setCurrentTab(int index) {
currentTab = index;
if (listener != null) {
listener.onTabChanged(getCurrentTabTag());
@@ -53,7 +53,7 @@ public class ShadowTabHost extends ShadowViewGroup {
}
@Implementation
- public void setCurrentTabByTag(String tag) {
+ protected void setCurrentTabByTag(String tag) {
for (int x = 0; x < tabSpecs.size(); x++) {
TabSpec tabSpec = tabSpecs.get(x);
if (tabSpec.getTag().equals(tag)) {
@@ -66,7 +66,7 @@ public class ShadowTabHost extends ShadowViewGroup {
}
@Implementation
- public int getCurrentTab() {
+ protected int getCurrentTab() {
if (currentTab == -1 && tabSpecs.size() > 0) currentTab = 0;
return currentTab;
}
@@ -76,7 +76,7 @@ public class ShadowTabHost extends ShadowViewGroup {
}
@Implementation
- public String getCurrentTabTag() {
+ protected String getCurrentTabTag() {
int i = getCurrentTab();
if (i >= 0 && i < tabSpecs.size()) {
return tabSpecs.get(i).getTag();
@@ -85,12 +85,12 @@ public class ShadowTabHost extends ShadowViewGroup {
}
@Implementation
- public void setOnTabChangedListener(android.widget.TabHost.OnTabChangeListener listener) {
+ protected void setOnTabChangedListener(android.widget.TabHost.OnTabChangeListener listener) {
this.listener = listener;
}
@Implementation
- public View getCurrentView() {
+ protected View getCurrentView() {
ShadowTabSpec ts = Shadow.extract(getCurrentTabSpec());
View v = ts.getContentView();
if (v == null) {
@@ -105,7 +105,7 @@ public class ShadowTabHost extends ShadowViewGroup {
}
@Implementation
- public TabWidget getTabWidget() {
+ protected TabWidget getTabWidget() {
Context context = realView.getContext();
if (context instanceof Activity) {
return (TabWidget) ((Activity)context).findViewById(R.id.tabs);
@@ -147,7 +147,7 @@ public class ShadowTabHost extends ShadowViewGroup {
}
@Implementation
- public String getTag() {
+ protected String getTag() {
return tag;
}
@@ -176,19 +176,19 @@ public class ShadowTabHost extends ShadowViewGroup {
}
@Implementation
- public TabSpec setIndicator(View view) {
+ protected TabSpec setIndicator(View view) {
this.indicatorView = view;
return realObject;
}
@Implementation
- public TabSpec setIndicator(CharSequence label) {
+ protected TabSpec setIndicator(CharSequence label) {
this.label = label;
return realObject;
}
@Implementation
- public TabSpec setIndicator(CharSequence label, Drawable icon) {
+ protected TabSpec setIndicator(CharSequence label, Drawable icon) {
this.label = label;
this.icon = icon;
return realObject;
@@ -202,19 +202,19 @@ public class ShadowTabHost extends ShadowViewGroup {
}
@Implementation
- public TabSpec setContent(Intent intent) {
+ protected TabSpec setContent(Intent intent) {
this.intent = intent;
return realObject;
}
@Implementation
- public TabSpec setContent(TabHost.TabContentFactory factory) {
+ protected TabSpec setContent(TabHost.TabContentFactory factory) {
contentView = factory.createTabContent(this.tag);
return realObject;
}
@Implementation
- public TabSpec setContent(int viewId) {
+ protected TabSpec setContent(int viewId) {
this.viewId = viewId;
return realObject;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelecomManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelecomManager.java
index a7c3c8712..9f600c762 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelecomManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelecomManager.java
@@ -17,6 +17,7 @@ import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
+import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
@@ -35,35 +36,40 @@ public class ShadowTelecomManager {
private String defaultDialerPackageName;
@Implementation
- public PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) {
+ protected PhoneAccountHandle getDefaultOutgoingPhoneAccount(String uriScheme) {
return null;
}
@Implementation
+ @HiddenApi
public PhoneAccountHandle getUserSelectedOutgoingPhoneAccount() {
return null;
}
@Implementation
+ @HiddenApi
public void setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle accountHandle) {
}
@Implementation
- public PhoneAccountHandle getSimCallManager() {
+ protected PhoneAccountHandle getSimCallManager() {
return simCallManager;
}
@Implementation(minSdk = M)
+ @HiddenApi
public PhoneAccountHandle getSimCallManager(int userId) {
return null;
}
@Implementation
+ @HiddenApi
public PhoneAccountHandle getConnectionManager() {
return this.getSimCallManager();
}
@Implementation
+ @HiddenApi
public List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(String uriScheme) {
List<PhoneAccountHandle> result = new ArrayList<>();
@@ -77,11 +83,12 @@ public class ShadowTelecomManager {
}
@Implementation(minSdk = M)
- public List<PhoneAccountHandle> getCallCapablePhoneAccounts() {
+ protected List<PhoneAccountHandle> getCallCapablePhoneAccounts() {
return this.getCallCapablePhoneAccounts(false);
}
@Implementation(minSdk = M)
+ @HiddenApi
public List<PhoneAccountHandle> getCallCapablePhoneAccounts(boolean includeDisabledAccounts) {
List<PhoneAccountHandle> result = new ArrayList<>();
@@ -96,6 +103,7 @@ public class ShadowTelecomManager {
}
@Implementation
+ @HiddenApi
public List<PhoneAccountHandle> getPhoneAccountsForPackage() {
Context context = ReflectionHelpers.getField(realObject, "mContext");
@@ -109,44 +117,49 @@ public class ShadowTelecomManager {
}
@Implementation
- public PhoneAccount getPhoneAccount(PhoneAccountHandle account) {
+ protected PhoneAccount getPhoneAccount(PhoneAccountHandle account) {
return accounts.get(account);
}
@Implementation
+ @HiddenApi
public int getAllPhoneAccountsCount() {
return accounts.size();
}
@Implementation
+ @HiddenApi
public List<PhoneAccount> getAllPhoneAccounts() {
return ImmutableList.copyOf(accounts.values());
}
@Implementation
+ @HiddenApi
public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
return ImmutableList.copyOf(accounts.keySet());
}
@Implementation
- public void registerPhoneAccount(PhoneAccount account) {
+ protected void registerPhoneAccount(PhoneAccount account) {
accounts.put(account.getAccountHandle(), account);
}
@Implementation
- public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
+ protected void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
accounts.remove(accountHandle);
}
/** @deprecated */
@Deprecated
@Implementation
+ @HiddenApi
public void clearAccounts() {
accounts.clear();
}
@Implementation(minSdk = LOLLIPOP_MR1)
+ @HiddenApi
public void clearAccountsForPackage(String packageName) {
Set<PhoneAccountHandle> phoneAccountHandlesInPackage = new HashSet<>();
@@ -164,81 +177,103 @@ public class ShadowTelecomManager {
/** @deprecated */
@Deprecated
@Implementation
+ @HiddenApi
public ComponentName getDefaultPhoneApp() {
return null;
}
@Implementation(minSdk = M)
- public String getDefaultDialerPackage() {
+ protected String getDefaultDialerPackage() {
return defaultDialerPackageName;
}
@Implementation(minSdk = M)
+ @HiddenApi
public boolean setDefaultDialer(String packageName) {
this.defaultDialerPackageName = packageName;
return true;
}
@Implementation(minSdk = M)
+ @HiddenApi
public String getSystemDialerPackage() {
return null;
}
@Implementation(minSdk = LOLLIPOP_MR1)
- public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) {
+ protected boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number) {
return false;
}
@Implementation(minSdk = M)
- public String getVoiceMailNumber(PhoneAccountHandle accountHandle) {
+ protected String getVoiceMailNumber(PhoneAccountHandle accountHandle) {
return null;
}
@Implementation(minSdk = LOLLIPOP_MR1)
- public String getLine1Number(PhoneAccountHandle accountHandle) {
+ protected String getLine1Number(PhoneAccountHandle accountHandle) {
return null;
}
@Implementation
- public boolean isInCall() {
+ protected boolean isInCall() {
return false;
}
@Implementation
+ @HiddenApi
public int getCallState() {
return 0;
}
@Implementation
+ @HiddenApi
public boolean isRinging() {
+ for (CallRecord callRecord : incomingCalls) {
+ if (callRecord.isRinging) {
+ return true;
+ }
+ }
+ for (CallRecord callRecord : unknownCalls) {
+ if (callRecord.isRinging) {
+ return true;
+ }
+ }
return false;
}
@Implementation
+ @HiddenApi
public boolean endCall() {
return false;
}
@Implementation
- public void acceptRingingCall() {
- }
+ protected void acceptRingingCall() {}
@Implementation
- public void silenceRinger() {
+ protected void silenceRinger() {
+ for (CallRecord callRecord : incomingCalls) {
+ callRecord.isRinging = false;
+ }
+ for (CallRecord callRecord : unknownCalls) {
+ callRecord.isRinging = false;
+ }
}
@Implementation
- public boolean isTtySupported() {
+ protected boolean isTtySupported() {
return false;
}
@Implementation
+ @HiddenApi
public int getCurrentTtyMode() {
return 0;
}
@Implementation
- public void addNewIncomingCall(PhoneAccountHandle phoneAccount, Bundle extras) {
+ protected void addNewIncomingCall(PhoneAccountHandle phoneAccount, Bundle extras) {
incomingCalls.add(new CallRecord(phoneAccount, extras));
}
@@ -247,6 +282,7 @@ public class ShadowTelecomManager {
}
@Implementation
+ @HiddenApi
public void addNewUnknownCall(PhoneAccountHandle phoneAccount, Bundle extras) {
unknownCalls.add(new CallRecord(phoneAccount, extras));
}
@@ -256,33 +292,31 @@ public class ShadowTelecomManager {
}
@Implementation
- public boolean handleMmi(String dialString) {
+ protected boolean handleMmi(String dialString) {
return false;
}
@Implementation(minSdk = M)
- public boolean handleMmi(String dialString, PhoneAccountHandle accountHandle) {
+ protected boolean handleMmi(String dialString, PhoneAccountHandle accountHandle) {
return false;
}
@Implementation(minSdk = LOLLIPOP_MR1)
- public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle) {
+ protected Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle) {
return Uri.parse("content://icc/adn");
}
@Implementation
- public void cancelMissedCallsNotification() {
- }
+ protected void cancelMissedCallsNotification() {}
@Implementation
- public void showInCallScreen(boolean showDialpad) {
- }
+ protected void showInCallScreen(boolean showDialpad) {}
@Implementation(minSdk = M)
- public void placeCall(Uri address, Bundle extras) {
- }
+ protected void placeCall(Uri address, Bundle extras) {}
@Implementation(minSdk = M)
+ @HiddenApi
public void enablePhoneAccount(PhoneAccountHandle handle, boolean isEnabled) {
}
@@ -293,6 +327,7 @@ public class ShadowTelecomManager {
public static class CallRecord {
public final PhoneAccountHandle phoneAccount;
public final Bundle bundle;
+ private boolean isRinging = true;
public CallRecord(PhoneAccountHandle phoneAccount, Bundle extras) {
this.phoneAccount = phoneAccount;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephony.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephony.java
new file mode 100644
index 000000000..7f3f57aec
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephony.java
@@ -0,0 +1,37 @@
+package org.robolectric.shadows;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.Build.VERSION_CODES;
+import android.provider.Telephony;
+import android.provider.Telephony.Sms;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@Implements(value = Telephony.class, minSdk = VERSION_CODES.KITKAT)
+public class ShadowTelephony {
+ @Implements(value = Sms.class, minSdk = VERSION_CODES.KITKAT)
+ public static class ShadowSms {
+ @Nullable private static String defaultSmsPackage;
+
+ @Implementation
+ protected static String getDefaultSmsPackage(Context context) {
+ return defaultSmsPackage;
+ }
+
+ /**
+ * Override the package name returned from calling {@link Sms#getDefaultSmsPackage(Context)}.
+ *
+ * <p>This will be reset for the next test.
+ */
+ public static void setDefaultSmsPackage(String defaultSmsPackage) {
+ ShadowSms.defaultSmsPackage = defaultSmsPackage;
+ }
+
+ @Resetter
+ public static synchronized void reset() {
+ defaultSmsPackage = null;
+ }
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextToSpeech.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextToSpeech.java
index 3ae6f536d..3be350401 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextToSpeech.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextToSpeech.java
@@ -1,14 +1,10 @@
package org.robolectric.shadows;
-import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import android.content.Context;
-import android.os.Build.VERSION;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
-import android.speech.tts.TextToSpeech.Engine;
-import android.speech.tts.UtteranceProgressListener;
import java.util.HashMap;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -21,7 +17,6 @@ public class ShadowTextToSpeech {
private boolean shutdown = false;
private boolean stopped = true;
private int queueMode = -1;
- private UtteranceProgressListener utteranceProgressListener;
@Implementation
protected void __constructor__(Context context, TextToSpeech.OnInitListener listener) {
@@ -29,41 +24,19 @@ public class ShadowTextToSpeech {
this.listener = listener;
}
- /**
- * Speaks the string using the specified queuing strategy and speech parameters.
- *
- * @param params The real implementation converts the hashmap into a bundle, but the bundle
- * argument is not used in the shadow implementation.
- */
@Implementation
- protected int speak(final String text, final int queueMode, final HashMap<String, String> params) {
- return speak(
- text,
- queueMode,
- null,
- params == null ? null : params.get(Engine.KEY_PARAM_UTTERANCE_ID));
- }
-
- @Implementation(minSdk = LOLLIPOP)
protected int speak(
- final CharSequence text, final int queueMode, final Bundle params, final String utteranceId) {
+ final String text, final int queueMode, final HashMap<String, String> params) {
stopped = false;
- lastSpokenText = text.toString();
+ lastSpokenText = text;
this.queueMode = queueMode;
-
- if (VERSION.SDK_INT >= ICE_CREAM_SANDWICH_MR1) {
- if (utteranceId != null && utteranceProgressListener != null) {
- utteranceProgressListener.onStart(utteranceId);
- utteranceProgressListener.onDone(utteranceId);
- }
- }
return TextToSpeech.SUCCESS;
}
- @Implementation(minSdk = ICE_CREAM_SANDWICH_MR1)
- protected int setOnUtteranceProgressListener(UtteranceProgressListener listener) {
- utteranceProgressListener = listener;
- return TextToSpeech.SUCCESS;
+ @Implementation(minSdk = LOLLIPOP)
+ protected int speak(
+ final CharSequence text, final int queueMode, final Bundle params, final String utteranceId) {
+ return speak(text.toString(), queueMode, new HashMap<>());
}
@Implementation
@@ -105,4 +78,4 @@ public class ShadowTextToSpeech {
public int getQueueMode() {
return queueMode;
}
-} \ No newline at end of file
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextUtils.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextUtils.java
index 2fa8b1e4b..e442a2396 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextUtils.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextUtils.java
@@ -14,7 +14,7 @@ import org.robolectric.annotation.Implements;
public class ShadowTextUtils {
@Implementation
- public static CharSequence ellipsize(
+ protected static CharSequence ellipsize(
CharSequence text, TextPaint p, float avail, TruncateAt where) {
// This shadow follows the convention of ShadowPaint#measureText where each
// characters width is 1.0.
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextView.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextView.java
index dfe70ddc0..f970b1078 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextView.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTextView.java
@@ -62,20 +62,20 @@ public class ShadowTextView extends ShadowView {
private int compoundDrawablesWithIntrinsicBoundsBottom;
@Implementation
- public void setTextAppearance(Context context, int resid) {
+ protected void setTextAppearance(Context context, int resid) {
textAppearanceId = resid;
directlyOn(realTextView, TextView.class).setTextAppearance(context, resid);
}
@Implementation
- public boolean onKeyDown(int keyCode, KeyEvent event) {
+ protected boolean onKeyDown(int keyCode, KeyEvent event) {
previousKeyCodes.add(keyCode);
previousKeyEvents.add(event);
return directlyOn(realTextView, TextView.class).onKeyDown(keyCode, event);
}
@Implementation
- public boolean onKeyUp(int keyCode, KeyEvent event) {
+ protected boolean onKeyUp(int keyCode, KeyEvent event) {
previousKeyCodes.add(keyCode);
previousKeyEvents.add(event);
return directlyOn(realTextView, TextView.class).onKeyUp(keyCode, event);
@@ -105,13 +105,13 @@ public class ShadowTextView extends ShadowView {
}
@Implementation
- public void addTextChangedListener(TextWatcher watcher) {
+ protected void addTextChangedListener(TextWatcher watcher) {
this.watchers.add(watcher);
directlyOn(realTextView, TextView.class).addTextChangedListener(watcher);
}
@Implementation
- public void removeTextChangedListener(TextWatcher watcher) {
+ protected void removeTextChangedListener(TextWatcher watcher) {
this.watchers.remove(watcher);
directlyOn(realTextView, TextView.class).removeTextChangedListener(watcher);
}
@@ -138,17 +138,17 @@ public class ShadowTextView extends ShadowView {
}
@Implementation
- public int getPaintFlags() {
+ protected int getPaintFlags() {
return paintFlags;
}
@Implementation
- public void setPaintFlags(int paintFlags) {
+ protected void setPaintFlags(int paintFlags) {
this.paintFlags = paintFlags;
}
@Implementation
- public void setOnEditorActionListener(TextView.OnEditorActionListener l) {
+ protected void setOnEditorActionListener(TextView.OnEditorActionListener l) {
this.onEditorActionListener = l;
directlyOn(realTextView, TextView.class).setOnEditorActionListener(l);
}
@@ -158,7 +158,7 @@ public class ShadowTextView extends ShadowView {
}
@Implementation
- public void setCompoundDrawablesWithIntrinsicBounds(int left, int top, int right, int bottom) {
+ protected void setCompoundDrawablesWithIntrinsicBounds(int left, int top, int right, int bottom) {
this.compoundDrawablesWithIntrinsicBoundsLeft = left;
this.compoundDrawablesWithIntrinsicBoundsTop = top;
this.compoundDrawablesWithIntrinsicBoundsRight = right;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowThreadedRenderer.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowThreadedRenderer.java
new file mode 100644
index 000000000..82cf66674
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowThreadedRenderer.java
@@ -0,0 +1,27 @@
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.LOLLIPOP;
+import static android.os.Build.VERSION_CODES.O;
+import static android.os.Build.VERSION_CODES.P;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.view.ThreadedRenderer;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadow.api.Shadow;
+
+@Implements(value = ThreadedRenderer.class, isInAndroidSdk = false, minSdk = LOLLIPOP, looseSignatures = true)
+public class ShadowThreadedRenderer {
+
+ @Implementation(minSdk = O, maxSdk = P)
+ protected static Bitmap createHardwareBitmap(Object rendererNode, Object width, Object height) {
+ int w = (int) width;
+ int h = (int) height;
+
+ Bitmap bitmap = Bitmap.createBitmap(w, h, Config.HARDWARE);
+ ShadowBitmap shadowBitmap = Shadow.extract(bitmap);
+ shadowBitmap.setMutable(false);
+ return bitmap;
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTile.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTile.java
index 0b55787ad..df1da4f97 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTile.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTile.java
@@ -5,7 +5,6 @@ import android.service.quicksettings.Tile;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
-/** Shadow for {@link Tile}. */
@Implements(value = Tile.class, minSdk = Build.VERSION_CODES.N)
public final class ShadowTile {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTileService.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTileService.java
index 2d05f43da..3b3b7c937 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTileService.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTileService.java
@@ -7,7 +7,6 @@ import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadow.api.Shadow;
-/** Shadow for {@link TileService}. */
@Implements(value = TileService.class, minSdk = Build.VERSION_CODES.N)
public final class ShadowTileService {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTime.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTime.java
index 74a97c4a3..1a649adf4 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTime.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTime.java
@@ -23,7 +23,7 @@ public class ShadowTime {
private Time time;
@Implementation(maxSdk = KITKAT_WATCH)
- public void setToNow() {
+ protected void setToNow() {
time.set(ShadowSystemClock.currentTimeMillis());
}
@@ -33,12 +33,12 @@ public class ShadowTime {
private static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
@Implementation(maxSdk = KITKAT_WATCH)
- public void __constructor__() {
+ protected void __constructor__() {
__constructor__(getCurrentTimezone());
}
@Implementation(maxSdk = KITKAT_WATCH)
- public void __constructor__(String timezone) {
+ protected void __constructor__(String timezone) {
if (timezone == null) {
throw new NullPointerException("timezone is null!");
}
@@ -49,12 +49,12 @@ public class ShadowTime {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public void __constructor__(Time other) {
+ protected void __constructor__(Time other) {
set(other);
}
@Implementation(maxSdk = KITKAT_WATCH)
- public void set(Time other) {
+ protected void set(Time other) {
time.timezone = other.timezone;
time.second = other.second;
time.minute = other.minute;
@@ -69,20 +69,20 @@ public class ShadowTime {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static boolean isEpoch(Time time) {
+ protected static boolean isEpoch(Time time) {
long millis = time.toMillis(true);
return getJulianDay(millis, 0) == Time.EPOCH_JULIAN_DAY;
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static int getJulianDay(long millis, long gmtoff) {
+ protected static int getJulianDay(long millis, long gmtoff) {
long offsetMillis = gmtoff * 1000;
long julianDay = (millis + offsetMillis) / DAY_IN_MILLIS;
return (int) julianDay + Time.EPOCH_JULIAN_DAY;
}
@Implementation(maxSdk = KITKAT_WATCH)
- public long setJulianDay(int julianDay) {
+ protected long setJulianDay(int julianDay) {
// Don't bother with the GMT offset since we don't know the correct
// value for the given Julian day. Just get close and then adjust
// the day.
@@ -105,7 +105,7 @@ public class ShadowTime {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public void set(long millis) {
+ protected void set(long millis) {
Calendar c = getCalendar();
c.setTimeInMillis(millis);
set(
@@ -119,13 +119,13 @@ public class ShadowTime {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public long toMillis(boolean ignoreDst) {
+ protected long toMillis(boolean ignoreDst) {
Calendar c = getCalendar();
return c.getTimeInMillis();
}
@Implementation(maxSdk = KITKAT_WATCH)
- public void set(int second, int minute, int hour, int monthDay, int month, int year) {
+ protected void set(int second, int minute, int hour, int monthDay, int month, int year) {
time.second = second;
time.minute = minute;
time.hour = hour;
@@ -139,12 +139,12 @@ public class ShadowTime {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public void set(int monthDay, int month, int year) {
+ protected void set(int monthDay, int month, int year) {
set(0, 0, 0, monthDay, month, year);
}
@Implementation(maxSdk = KITKAT_WATCH)
- public void clear(String timezone) {
+ protected void clear(String timezone) {
if (timezone == null) {
throw new NullPointerException("timezone is null!");
}
@@ -163,12 +163,12 @@ public class ShadowTime {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static String getCurrentTimezone() {
+ protected static String getCurrentTimezone() {
return TimeZone.getDefault().getID();
}
@Implementation(maxSdk = KITKAT_WATCH)
- public void switchTimezone(String timezone) {
+ protected void switchTimezone(String timezone) {
long date = toMillis(true);
long gmtoff = TimeZone.getTimeZone(timezone).getOffset(date);
set(date + gmtoff);
@@ -177,7 +177,7 @@ public class ShadowTime {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public static int compare(Time a, Time b) {
+ protected static int compare(Time a, Time b) {
long ams = a.toMillis(false);
long bms = b.toMillis(false);
if (ams == bms) {
@@ -190,17 +190,17 @@ public class ShadowTime {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public boolean before(Time other) {
+ protected boolean before(Time other) {
return Time.compare(time, other) < 0;
}
@Implementation(maxSdk = KITKAT_WATCH)
- public boolean after(Time other) {
+ protected boolean after(Time other) {
return Time.compare(time, other) > 0;
}
@Implementation(maxSdk = KITKAT_WATCH)
- public boolean parse(String timeString) {
+ protected boolean parse(String timeString) {
TimeZone tz;
if (timeString.endsWith("Z")) {
timeString = timeString.substring(0, timeString.length() - 1);
@@ -226,7 +226,7 @@ public class ShadowTime {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public String format2445() {
+ protected String format2445() {
String value = format("%Y%m%dT%H%M%S");
if ( "UTC".equals(time.timezone)){
value += "Z";
@@ -235,7 +235,7 @@ public class ShadowTime {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public String format3339(boolean allDay) {
+ protected String format3339(boolean allDay) {
if (allDay) {
return format("%Y-%m-%d");
} else if ("UTC".equals(time.timezone)) {
@@ -251,7 +251,7 @@ public class ShadowTime {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public boolean parse3339(String rfc3339String) {
+ protected boolean parse3339(String rfc3339String) {
SimpleDateFormat formatter = new SimpleDateFormat();
// Special case Date without time first
if (rfc3339String.matches("\\d{4}-\\d{2}-\\d{2}")) {
@@ -312,7 +312,7 @@ public class ShadowTime {
}
@Implementation(maxSdk = KITKAT_WATCH)
- public String format(String format) {
+ protected String format(String format) {
return Strftime.format(format, new Date(toMillis(false)), Locale.getDefault(), TimeZone.getTimeZone(time.timezone));
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimePickerDialog.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimePickerDialog.java
index 5004c0bab..9e8bafb8f 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimePickerDialog.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimePickerDialog.java
@@ -17,7 +17,7 @@ public class ShadowTimePickerDialog extends ShadowAlertDialog {
private int minute;
@Implementation
- public void __constructor__(
+ protected void __constructor__(
Context context,
int theme,
TimePickerDialog.OnTimeSetListener callBack,
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinder.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinder.java
index c726b050d..8e18444fd 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinder.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinder.java
@@ -10,8 +10,7 @@ import libcore.util.TimeZoneFinder;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
-/** Shadow for {@code TimeZoneFinder}. */
-@Implements(value = TimeZoneFinder.class, minSdk = O, isInAndroidSdk = false)
+@Implements(value = TimeZoneFinder.class, minSdk = O, isInAndroidSdk = false, looseSignatures = true)
public class ShadowTimeZoneFinder {
private static final String TZLOOKUP_PATH = "/usr/share/zoneinfo/tzlookup.xml";
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTypeface.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTypeface.java
index 1af038599..6e05dc32b 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTypeface.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTypeface.java
@@ -2,6 +2,7 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static android.os.Build.VERSION_CODES.N_MR1;
+import static android.os.Build.VERSION_CODES.O;
import static android.os.Build.VERSION_CODES.P;
import static org.robolectric.RuntimeEnvironment.getApiLevel;
@@ -74,6 +75,11 @@ public class ShadowTypeface {
throw new RuntimeException("Font asset not found " + path);
}
+ @Implementation(minSdk = O)
+ protected static Typeface createFromResources(AssetManager mgr, String path, int cookie) {
+ return createUnderlyingTypeface(path, Typeface.NORMAL);
+ }
+
@Implementation
protected static Typeface createFromFile(File path) {
String familyName = path.toPath().getFileName().toString();
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsageStatsManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsageStatsManager.java
index 39d864fa7..2d2a5af49 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsageStatsManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsageStatsManager.java
@@ -15,6 +15,7 @@ import android.os.Parcel;
import android.util.ArraySet;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Range;
import com.google.common.collect.SetMultimap;
import java.util.ArrayList;
@@ -151,7 +152,7 @@ public class ShadowUsageStatsManager {
/**
* Adds an event to be returned by {@link UsageStatsManager#queryEvents}.
*
- * <p>This method won't affect the results of {@link #queryUsageStats} method.
+ * This method won't affect the results of {@link #queryUsageStats} method.
*
* @deprecated Use {@link #addEvent(Event)} and {@link EventBuilder} instead.
*/
@@ -171,18 +172,40 @@ public class ShadowUsageStatsManager {
/**
* Adds an event to be returned by {@link UsageStatsManager#queryEvents}.
*
- * <p>This method won't affect the results of {@link #queryUsageStats} method.
+ * This method won't affect the results of {@link #queryUsageStats} method.
*
- * <p>The {@link Event} can be built by {@link EventBuilder}.
+ * The {@link Event} can be built by {@link EventBuilder}.
*/
public void addEvent(Event event) {
eventsByTimeStamp.put(event.getTimeStamp(), event);
}
/**
+ * Simulates the operations done by the framework when there is a time change. If the time is
+ * changed, the timestamps of all existing usage events will be shifted by the same offset as the
+ * time change, in order to make sure they remain stable relative to the new time.
+ *
+ * This method won't affect the results of {@link #queryUsageStats} method.
+ *
+ * @param offsetToAddInMillis the offset to be applied to all events. For example, if {@code
+ * offsetInMillis} is 60,000, then all {@link Event}s will be shifted forward by 1 minute
+ * (into the future). Likewise, if {@code offsetInMillis} is -60,000, then all {@link Event}s
+ * will be shifted backward by 1 minute (into the past).
+ */
+ public void simulateTimeChange(long offsetToAddInMillis) {
+ ImmutableMap.Builder<Long, Event> eventMapBuilder = ImmutableMap.builder();
+ for (Event event : eventsByTimeStamp.values()) {
+ long newTimestamp = event.getTimeStamp() + offsetToAddInMillis;
+ eventMapBuilder.put(
+ newTimestamp, EventBuilder.fromEvent(event).setTimeStamp(newTimestamp).build());
+ }
+ eventsByTimeStamp.putAll(eventMapBuilder.build());
+ }
+
+ /**
* Returns aggregated UsageStats added by calling {@link #addUsageStats}.
*
- * <p>The real implementation creates these aggregated objects from individual {@link Event}. This
+ * The real implementation creates these aggregated objects from individual {@link Event}. This
* aggregation logic is nontrivial, so the shadow implementation just returns the aggregate data
* added using {@link #addUsageStats}.
*/
@@ -216,23 +239,27 @@ public class ShadowUsageStatsManager {
* UsageStatsManager.STANDBY_BUCKET_ACTIVE}.
*/
@Implementation(minSdk = Build.VERSION_CODES.P)
+ @HiddenApi
public @StandbyBuckets int getAppStandbyBucket(String packageName) {
Integer bucket = appStandbyBuckets.get(packageName);
return (bucket == null) ? UsageStatsManager.STANDBY_BUCKET_ACTIVE : bucket;
}
@Implementation(minSdk = Build.VERSION_CODES.P)
+ @HiddenApi
public Map<String, Integer> getAppStandbyBuckets() {
return new HashMap<>(appStandbyBuckets);
}
/** Sets the standby bucket of the specified app. */
@Implementation(minSdk = Build.VERSION_CODES.P)
+ @HiddenApi
public void setAppStandbyBucket(String packageName, @StandbyBuckets int bucket) {
appStandbyBuckets.put(packageName, bucket);
}
@Implementation(minSdk = Build.VERSION_CODES.P)
+ @HiddenApi
public void setAppStandbyBuckets(Map<String, Integer> appBuckets) {
appStandbyBuckets.putAll(appBuckets);
}
@@ -265,7 +292,7 @@ public class ShadowUsageStatsManager {
/**
* Triggers a currently registered {@link AppUsageObserver} with {@code observerId}.
*
- * <p>The observer will be no longer registered afterwards.
+ * The observer will be no longer registered afterwards.
*/
public void triggerRegisteredAppUsageObserver(int observerId, long timeUsedInMillis) {
AppUsageObserver observer = appUsageObserversById.remove(observerId);
@@ -288,7 +315,8 @@ public class ShadowUsageStatsManager {
* UsageStatsManager.STANDBY_BUCKET_ACTIVE}.
*/
@Implementation(minSdk = Build.VERSION_CODES.P)
- public @StandbyBuckets int getAppStandbyBucket() {
+ @StandbyBuckets
+ protected int getAppStandbyBucket() {
return currentAppStandbyBucket;
}
@@ -359,6 +387,20 @@ public class ShadowUsageStatsManager {
private EventBuilder() {}
+ public static EventBuilder fromEvent(Event event) {
+ EventBuilder eventBuilder =
+ new EventBuilder()
+ .setPackage(event.mPackage)
+ .setClass(event.mClass)
+ .setTimeStamp(event.mTimeStamp)
+ .setEventType(event.mEventType)
+ .setConfiguration(event.mConfiguration);
+ if (event.mEventType == Event.CONFIGURATION_CHANGE) {
+ eventBuilder.setConfiguration(new Configuration());
+ }
+ return eventBuilder;
+ }
+
public static EventBuilder buildEvent() {
return new EventBuilder();
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java
index 6a5804fae..0cbdab7e4 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUserManager.java
@@ -2,11 +2,11 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
-import static android.os.Build.VERSION_CODES.KITKAT_WATCH;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.N;
import static android.os.Build.VERSION_CODES.N_MR1;
+import static org.robolectric.shadow.api.Shadow.directlyOn;
import android.Manifest.permission;
import android.content.Context;
@@ -20,11 +20,14 @@ import android.os.UserManager;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.annotation.Resetter;
/**
* Robolectric implementation of {@link android.os.UserManager}.
@@ -32,29 +35,33 @@ import org.robolectric.annotation.Implements;
@Implements(value = UserManager.class, minSdk = JELLY_BEAN_MR1)
public class ShadowUserManager {
+ /**
+ * The default user ID user for secondary user testing, when the ID is not otherwise specified.
+ */
+ public static final int DEFAULT_SECONDARY_USER_ID = 10;
+
+ private static Map<Integer, Integer> userPidMap = new HashMap<>();
+
+ @RealObject private UserManager realObject;
+
private boolean userUnlocked = true;
private boolean managedProfile = false;
- private boolean isDemoUser = false;
- private boolean isAdminUser = false;
private boolean isSystemUser = true;
- private boolean isPrimaryUser = true;
- private boolean isLinkedUser = false;
- private boolean isGuestUser = false;
- private Map<UserHandle, Bundle> userRestrictions = new HashMap<>();
+ private Map<Integer, Bundle> userRestrictions = new HashMap<>();
private BiMap<UserHandle, Long> userProfiles = HashBiMap.create();
private Map<String, Bundle> applicationRestrictions = new HashMap<>();
private long nextUserSerial = 0;
- private Map<UserHandle, UserState> userState = new HashMap<>();
+ private Map<Integer, UserState> userState = new HashMap<>();
+ private Map<Integer, UserInfo> userInfoMap = new HashMap<>();
+
private Context context;
private boolean enforcePermissions;
+ private boolean canSwitchUser = false;
@Implementation
protected void __constructor__(Context context, IUserManager service) {
this.context = context;
- }
-
- public ShadowUserManager() {
- addUserProfile(Process.myUserHandle());
+ addUser(UserHandle.USER_SYSTEM, "system_user", UserInfo.FLAG_PRIMARY | UserInfo.FLAG_ADMIN);
}
/**
@@ -138,7 +145,7 @@ public class ShadowUserManager {
@Implementation(minSdk = LOLLIPOP)
protected boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) {
- Bundle bundle = userRestrictions.get(userHandle);
+ Bundle bundle = userRestrictions.get(userHandle.getIdentifier());
return bundle != null && bundle.getBoolean(restrictionKey);
}
@@ -151,7 +158,7 @@ public class ShadowUserManager {
* Removes all user restrictions set of a user identified by {@code userHandle}.
*/
public void clearUserRestrictions(UserHandle userHandle) {
- userRestrictions.remove(userHandle);
+ userRestrictions.remove(userHandle.getIdentifier());
}
@Implementation(minSdk = JELLY_BEAN_MR2)
@@ -160,10 +167,10 @@ public class ShadowUserManager {
}
private Bundle getUserRestrictionsForUser(UserHandle userHandle) {
- Bundle bundle = userRestrictions.get(userHandle);
+ Bundle bundle = userRestrictions.get(userHandle.getIdentifier());
if (bundle == null) {
bundle = new Bundle();
- userRestrictions.put(userHandle, bundle);
+ userRestrictions.put(userHandle.getIdentifier(), bundle);
}
return bundle;
}
@@ -212,15 +219,24 @@ public class ShadowUserManager {
*/
@Implementation(minSdk = N_MR1)
protected boolean isDemoUser() {
- return isDemoUser;
+ return getUserInfo(UserHandle.myUserId()).isDemo();
}
/**
- * Sets that the current user is a demo user; controls the return value of
- * {@link UserManager#isDemoUser()}.
+ * Sets that the current user is a demo user; controls the return value of {@link
+ * UserManager#isDemoUser()}.
+ *
+ * @deprecated Use {@link ShadowUserManager#addUser(int, String, int)} to create a demo user
+ * instead of changing default user flags.
*/
+ @Deprecated
public void setIsDemoUser(boolean isDemoUser) {
- this.isDemoUser = isDemoUser;
+ UserInfo userInfo = getUserInfo(UserHandle.myUserId());
+ if (isDemoUser) {
+ userInfo.flags |= UserInfo.FLAG_DEMO;
+ } else {
+ userInfo.flags &= ~UserInfo.FLAG_DEMO;
+ }
}
/**
@@ -228,7 +244,7 @@ public class ShadowUserManager {
*/
@Implementation(minSdk = N_MR1)
public boolean isAdminUser() {
- return isAdminUser;
+ return getUserInfo(UserHandle.myUserId()).isAdmin();
}
/**
@@ -236,7 +252,12 @@ public class ShadowUserManager {
* {@link UserManager#isAdminUser}.
*/
public void setIsAdminUser(boolean isAdminUser) {
- this.isAdminUser = isAdminUser;
+ UserInfo userInfo = getUserInfo(UserHandle.myUserId());
+ if (isAdminUser) {
+ userInfo.flags |= UserInfo.FLAG_ADMIN;
+ } else {
+ userInfo.flags &= ~UserInfo.FLAG_ADMIN;
+ }
}
/**
@@ -244,31 +265,40 @@ public class ShadowUserManager {
*/
@Implementation(minSdk = M)
protected boolean isSystemUser() {
- return isSystemUser;
+ if (isSystemUser == false) {
+ return false;
+ } else {
+ return directlyOn(realObject, UserManager.class, "isSystemUser");
+ }
}
/**
- * Sets that the current user is the system user; controls the return value of
- * {@link UserManager#isSystemUser()}.
+ * Sets that the current user is the system user; controls the return value of {@link
+ * UserManager#isSystemUser()}.
+ *
+ * @deprecated Use {@link ShadowUserManager#addUser(int, String, int)} to create a system user
+ * instead of changing default user flags.
*/
+ @Deprecated
public void setIsSystemUser(boolean isSystemUser) {
this.isSystemUser = isSystemUser;
}
/**
- * @return 'true' by default, or the value specified via {@link #setIsPrimaryUser(boolean)}
- */
- @Implementation(minSdk = N)
- protected boolean isPrimaryUser() {
- return isPrimaryUser;
- }
-
- /**
- * Sets that the current user is the primary user; controls the return value of
- * {@link UserManager#isPrimaryUser()}.
+ * Sets that the current user is the primary user; controls the return value of {@link
+ * UserManager#isPrimaryUser()}.
+ *
+ * @deprecated Use {@link ShadowUserManager#addUser(int, String, int)} to create a primary user
+ * instead of changing default user flags.
*/
+ @Deprecated
public void setIsPrimaryUser(boolean isPrimaryUser) {
- this.isPrimaryUser = isPrimaryUser;
+ UserInfo userInfo = getUserInfo(UserHandle.myUserId());
+ if (isPrimaryUser) {
+ userInfo.flags |= UserInfo.FLAG_PRIMARY;
+ } else {
+ userInfo.flags &= ~UserInfo.FLAG_PRIMARY;
+ }
}
/**
@@ -276,31 +306,41 @@ public class ShadowUserManager {
*/
@Implementation(minSdk = JELLY_BEAN_MR2)
protected boolean isLinkedUser() {
- return isLinkedUser;
- }
-
- /**
- * Sets that the current user is the linked user; controls the return value of
- * {@link UserManager#isLinkedUser()}.
- */
- public void setIsLinkedUser (boolean isLinkedUser) {
- this.isLinkedUser = isLinkedUser;
+ return getUserInfo(UserHandle.myUserId()).isRestricted();
}
/**
- * @return 'false' by default, or the value specified via {@link #setIsGuestUser(boolean)}
+ * Sets that the current user is the linked user; controls the return value of {@link
+ * UserManager#isLinkedUser()}.
+ *
+ * @deprecated Use {@link ShadowUserManager#addUser(int, String, int)} to create a linked user
+ * instead of changing default user flags.
*/
- @Implementation(minSdk = KITKAT_WATCH)
- protected boolean isGuestUser() {
- return isGuestUser;
+ @Deprecated
+ public void setIsLinkedUser(boolean isLinkedUser) {
+ UserInfo userInfo = getUserInfo(UserHandle.myUserId());
+ if (isLinkedUser) {
+ userInfo.flags |= UserInfo.FLAG_RESTRICTED;
+ } else {
+ userInfo.flags &= ~UserInfo.FLAG_RESTRICTED;
+ }
}
/**
- * Sets that the current user is the guest user; controls the return value of
- * {@link UserManager#isGuestUser()}.
+ * Sets that the current user is the guest user; controls the return value of {@link
+ * UserManager#isGuestUser()}.
+ *
+ * @deprecated Use {@link ShadowUserManager#addUser(int, String, int)} to create a guest user
+ * instead of changing default user flags.
*/
- public void setIsGuestUser (boolean isGuestUser) {
- this.isGuestUser = isGuestUser;
+ @Deprecated
+ public void setIsGuestUser(boolean isGuestUser) {
+ UserInfo userInfo = getUserInfo(UserHandle.myUserId());
+ if (isGuestUser) {
+ userInfo.flags |= UserInfo.FLAG_GUEST;
+ } else {
+ userInfo.flags &= ~UserInfo.FLAG_GUEST;
+ }
}
/**
@@ -309,7 +349,7 @@ public class ShadowUserManager {
@Implementation
protected boolean isUserRunning(UserHandle handle) {
checkPermissions();
- UserState state = userState.get(handle);
+ UserState state = userState.get(handle.getIdentifier());
if (state == UserState.STATE_RUNNING_LOCKED
|| state == UserState.STATE_RUNNING_UNLOCKED
@@ -326,7 +366,7 @@ public class ShadowUserManager {
@Implementation
protected boolean isUserRunningOrStopping(UserHandle handle) {
checkPermissions();
- UserState state = userState.get(handle);
+ UserState state = userState.get(handle.getIdentifier());
if (state == UserState.STATE_RUNNING_LOCKED
|| state == UserState.STATE_RUNNING_UNLOCKED
@@ -362,15 +402,81 @@ public class ShadowUserManager {
* and {@link UserManager#isUserRunningOrStopping(UserHandle)}
*/
public void setUserState(UserHandle handle, UserState state) {
- userState.put(handle, state);
+ userState.put(handle.getIdentifier(), state);
}
- /**
- * @return an empty list
- */
@Implementation
protected List<UserInfo> getUsers() {
- // Implement this - return empty list to avoid NPE from call to getUserCount()
- return ImmutableList.of();
+ return new ArrayList<UserInfo>(userInfoMap.values());
+ }
+
+ @Implementation
+ protected UserInfo getUserInfo(int userHandle) {
+ return userInfoMap.get(userHandle);
+ }
+
+ /**
+ * Returns {@code true} by default, or the value specified via {@link #setCanSwitchUser(boolean)}.
+ */
+ @Implementation(minSdk = N)
+ protected boolean canSwitchUsers() {
+ return canSwitchUser;
+ }
+
+ /**
+ * Sets whether switching users is allowed or not; controls the return value of {@link
+ * UserManager#canSwitchUser()}
+ */
+ public void setCanSwitchUser(boolean canSwitchUser) {
+ this.canSwitchUser = canSwitchUser;
+ }
+
+ @Implementation(minSdk = JELLY_BEAN_MR1)
+ protected boolean removeUser(int userHandle) {
+ userInfoMap.remove(userHandle);
+ return true;
+ }
+
+ /**
+ * Switches the current user to {@code userHandle}.
+ *
+ * @param userId the integer handle of the user, where 0 is the primary user.
+ */
+ public void switchUser(int userId) {
+ if (!userInfoMap.containsKey(userId)) {
+ throw new UnsupportedOperationException("Must add user before switching to it");
+ }
+
+ ShadowProcess.setUid(userPidMap.get(userId));
+ }
+
+ /**
+ * Creates a user with the specified name, userId and flags.
+ *
+ * @param id the unique id of user
+ * @param name name of the user
+ * @param flags 16 bits for user type. See {@link UserInfo#flags}
+ */
+ public void addUser(int id, String name, int flags) {
+ UserHandle userHandle =
+ id == UserHandle.USER_SYSTEM ? Process.myUserHandle() : new UserHandle(id);
+ addUserProfile(userHandle);
+ setSerialNumberForUser(userHandle, (long) id);
+ userInfoMap.put(id, new UserInfo(id, name, flags));
+ userPidMap.put(
+ id,
+ id == UserHandle.USER_SYSTEM
+ ? Process.myUid()
+ : id * UserHandle.PER_USER_RANGE + ShadowProcess.getRandomApplicationUid());
+ }
+
+ @Resetter
+ public static void reset() {
+ if (userPidMap != null && userPidMap.isEmpty() == false) {
+ ShadowProcess.setUid(userPidMap.get(UserHandle.USER_SYSTEM));
+
+ userPidMap.clear();
+ userPidMap.put(UserHandle.USER_SYSTEM, Process.myUid());
+ }
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVMRuntime.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVMRuntime.java
index 065ac30af..d4bc397da 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVMRuntime.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVMRuntime.java
@@ -2,11 +2,13 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
+import android.annotation.TargetApi;
import dalvik.system.VMRuntime;
import java.lang.reflect.Array;
import javax.annotation.Nullable;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
import org.robolectric.res.android.NativeObjRegistry;
@Implements(value = VMRuntime.class, isInAndroidSdk = false)
@@ -14,6 +16,10 @@ public class ShadowVMRuntime {
private final NativeObjRegistry<Object> nativeObjRegistry =
new NativeObjRegistry<>("VRRuntime.nativeObjectRegistry");
+ // There actually isn't any android JNI code to call through to in Robolectric due to
+ // cross-platform compatibility issues. We default to a reasonable value that reflects the devices
+ // that would commonly run this code.
+ private static boolean is64Bit = true;
@Implementation(minSdk = LOLLIPOP)
public Object newUnpaddedArray(Class<?> klass, int size) {
@@ -43,4 +49,23 @@ public class ShadowVMRuntime {
Object getObjectForAddress(long address) {
return nativeObjRegistry.getNativeObject(address);
}
+
+ /**
+ * Returns whether the VM is running in 64-bit mode. Available in Android L+. Defaults to true.
+ */
+ @Implementation(minSdk = LOLLIPOP)
+ protected boolean is64Bit() {
+ return ShadowVMRuntime.is64Bit;
+ }
+
+ /** Sets whether the VM is running in 64-bit mode. */
+ @TargetApi(LOLLIPOP)
+ public static void setIs64Bit(boolean is64Bit) {
+ ShadowVMRuntime.is64Bit = is64Bit;
+ }
+
+ @Resetter
+ public static void reset() {
+ ShadowVMRuntime.is64Bit = true;
+ }
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowValueAnimator.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowValueAnimator.java
index 4b4acad27..3a0132a01 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowValueAnimator.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowValueAnimator.java
@@ -43,7 +43,7 @@ public class ShadowValueAnimator {
}
@Implementation
- public void setRepeatCount(int count) {
+ protected void setRepeatCount(int count) {
actualRepeatCount = count;
if (count == ValueAnimator.INFINITE) {
count = 1;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVectorDrawable.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVectorDrawable.java
index d48f72a6b..0153f5997 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVectorDrawable.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVectorDrawable.java
@@ -79,20 +79,18 @@ public class ShadowVectorDrawable extends ShadowDrawable {
return get(pathPtr, Path.class);
}
-
@Implementation
- public static long nCreateFullPath() {
+ protected static long nCreateFullPath() {
return put(new Path());
}
@Implementation
- public static long nCreateFullPath(long nativeFullPathPtr) {
+ protected static long nCreateFullPath(long nativeFullPathPtr) {
return put(getPath(nativeFullPathPtr).clone());
}
@Implementation
- public static boolean nGetFullPathProperties(long pathPtr, byte[] properties,
- int length) {
+ protected static boolean nGetFullPathProperties(long pathPtr, byte[] properties, int length) {
if (length != TOTAL_PROPERTY_COUNT * 4) return false;
Path path = getPath(pathPtr);
@@ -115,10 +113,20 @@ public class ShadowVectorDrawable extends ShadowDrawable {
}
@Implementation
- public static void nUpdateFullPathProperties(long pathPtr, float strokeWidth,
- int strokeColor, float strokeAlpha, int fillColor, float fillAlpha, float trimPathStart,
- float trimPathEnd, float trimPathOffset, float strokeMiterLimit, int strokeLineCap,
- int strokeLineJoin, int fillType) {
+ protected static void nUpdateFullPathProperties(
+ long pathPtr,
+ float strokeWidth,
+ int strokeColor,
+ float strokeAlpha,
+ int fillColor,
+ float fillAlpha,
+ float trimPathStart,
+ float trimPathEnd,
+ float trimPathOffset,
+ float strokeMiterLimit,
+ int strokeLineCap,
+ int strokeLineJoin,
+ int fillType) {
Path path = getPath(pathPtr);
path.strokeWidth = strokeWidth;
path.strokeColor = strokeColor;
@@ -172,21 +180,20 @@ public class ShadowVectorDrawable extends ShadowDrawable {
}
@Implementation
- public static long nCreateGroup() {
+ protected static long nCreateGroup() {
return put(new Group());
}
@Implementation
- public static long nCreateGroup(long groupPtr) {
+ protected static long nCreateGroup(long groupPtr) {
return put(getGroup(groupPtr).clone());
}
-// public static void nSetName(long nodePtr, String name) {
-// }
+ // public static void nSetName(long nodePtr, String name) {
+ // }
@Implementation
- public static boolean nGetGroupProperties(long groupPtr, float[] properties,
- int length) {
+ protected static boolean nGetGroupProperties(long groupPtr, float[] properties, int length) {
if (length != 7) return false;
Group group = getGroup(groupPtr);
properties[0] = group.rotation;
@@ -200,8 +207,15 @@ public class ShadowVectorDrawable extends ShadowDrawable {
}
@Implementation
- public static void nUpdateGroupProperties(long groupPtr, float rotate, float pivotX,
- float pivotY, float scaleX, float scaleY, float translateX, float translateY) {
+ protected static void nUpdateGroupProperties(
+ long groupPtr,
+ float rotate,
+ float pivotX,
+ float pivotY,
+ float scaleX,
+ float scaleY,
+ float translateX,
+ float translateY) {
Group group = getGroup(groupPtr);
group.rotation = rotate;
group.pivotX = pivotX;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVelocityTracker.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVelocityTracker.java
index 478e1f7a5..aed29a460 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVelocityTracker.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVelocityTracker.java
@@ -33,7 +33,7 @@ public class ShadowVelocityTracker {
}
@Implementation
- public void clear() {
+ protected void clear() {
maybeInitialize();
curIndex = 0;
computedVelocityX.clear();
@@ -44,7 +44,7 @@ public class ShadowVelocityTracker {
}
@Implementation
- public void addMovement(MotionEvent event) {
+ protected void addMovement(MotionEvent event) {
maybeInitialize();
if (event == null) {
throw new IllegalArgumentException("event must not be null");
@@ -62,12 +62,12 @@ public class ShadowVelocityTracker {
}
@Implementation
- public void computeCurrentVelocity(int units) {
+ protected void computeCurrentVelocity(int units) {
computeCurrentVelocity(units, Float.MAX_VALUE);
}
@Implementation
- public void computeCurrentVelocity(int units, float maxVelocity) {
+ protected void computeCurrentVelocity(int units, float maxVelocity) {
maybeInitialize();
// Estimation based on AOSP's LegacyVelocityTrackerStrategy
@@ -129,17 +129,17 @@ public class ShadowVelocityTracker {
}
@Implementation
- public float getXVelocity() {
+ protected float getXVelocity() {
return getXVelocity(ACTIVE_POINTER_ID);
}
@Implementation
- public float getYVelocity() {
+ protected float getYVelocity() {
return getYVelocity(ACTIVE_POINTER_ID);
}
@Implementation
- public float getXVelocity(int id) {
+ protected float getXVelocity(int id) {
if (id == ACTIVE_POINTER_ID) {
id = activePointerId;
}
@@ -148,7 +148,7 @@ public class ShadowVelocityTracker {
}
@Implementation
- public float getYVelocity(int id) {
+ protected float getYVelocity(int id) {
if (id == ACTIVE_POINTER_ID) {
id = activePointerId;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVideoView.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVideoView.java
index 157b91236..2b6a10659 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVideoView.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVideoView.java
@@ -28,84 +28,84 @@ public class ShadowVideoView extends ShadowSurfaceView {
private int currentPosition;
@Implementation
- public void setOnPreparedListener(MediaPlayer.OnPreparedListener l) {
+ protected void setOnPreparedListener(MediaPlayer.OnPreparedListener l) {
preparedListener = l;
}
@Implementation
- public void setOnErrorListener(MediaPlayer.OnErrorListener l) {
+ protected void setOnErrorListener(MediaPlayer.OnErrorListener l) {
errorListener = l;
}
@Implementation
- public void setOnCompletionListener(MediaPlayer.OnCompletionListener l) {
+ protected void setOnCompletionListener(MediaPlayer.OnCompletionListener l) {
completionListner = l;
}
@Implementation
- public void setVideoPath(String path) {
+ protected void setVideoPath(String path) {
this.path = path;
}
@Implementation
- public void setVideoURI(Uri uri) {
+ protected void setVideoURI(Uri uri) {
this.uri = uri;
}
@Implementation
- public void start() {
+ protected void start() {
savePrevState();
currentState = ShadowVideoView.START;
}
@Implementation
- public void stopPlayback() {
+ protected void stopPlayback() {
savePrevState();
currentState = ShadowVideoView.STOP;
}
@Implementation
- public void suspend() {
+ protected void suspend() {
savePrevState();
currentState = ShadowVideoView.SUSPEND;
}
@Implementation
- public void pause() {
+ protected void pause() {
savePrevState();
currentState = ShadowVideoView.PAUSE;
}
@Implementation
- public void resume() {
+ protected void resume() {
savePrevState();
currentState = ShadowVideoView.RESUME;
}
@Implementation
- public boolean isPlaying() {
+ protected boolean isPlaying() {
return (currentState == ShadowVideoView.START);
}
@Implementation
- public boolean canPause() {
+ protected boolean canPause() {
return (currentState != ShadowVideoView.PAUSE &&
currentState != ShadowVideoView.STOP &&
currentState != ShadowVideoView.SUSPEND);
}
@Implementation
- public void seekTo(int msec) {
+ protected void seekTo(int msec) {
currentPosition = msec;
}
@Implementation
- public int getCurrentPosition() {
+ protected int getCurrentPosition() {
return currentPosition;
}
@Implementation
- public int getDuration() {
+ protected int getDuration() {
return duration;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowView.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowView.java
index 611e4fd1a..e151e4024 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowView.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowView.java
@@ -9,7 +9,6 @@ import static org.robolectric.util.ReflectionHelpers.setField;
import android.annotation.SuppressLint;
import android.content.Context;
-import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
@@ -354,19 +353,21 @@ public class ShadowView {
return onCreateContextMenuListener;
}
- @Implementation
- protected Bitmap getDrawingCache() {
- return ReflectionHelpers.callConstructor(Bitmap.class);
- }
+ // @Implementation
+ // protected Bitmap getDrawingCache() {
+ // return ReflectionHelpers.callConstructor(Bitmap.class);
+ // }
@Implementation
- protected void post(Runnable action) {
+ protected boolean post(Runnable action) {
ShadowApplication.getInstance().getForegroundThreadScheduler().post(action);
+ return true;
}
@Implementation
- protected void postDelayed(Runnable action, long delayMills) {
+ protected boolean postDelayed(Runnable action, long delayMills) {
ShadowApplication.getInstance().getForegroundThreadScheduler().postDelayed(action, delayMills);
+ return true;
}
@Implementation
@@ -380,9 +381,10 @@ public class ShadowView {
}
@Implementation
- protected void removeCallbacks(Runnable callback) {
+ protected boolean removeCallbacks(Runnable callback) {
ShadowLooper shadowLooper = Shadow.extract(Looper.getMainLooper());
shadowLooper.getScheduler().remove(callback);
+ return true;
}
@Implementation
@@ -473,9 +475,9 @@ public class ShadowView {
if ((animation.getStartTime() == startTime && animation.getStartOffset() == startOffset) &&
animation.getTransformation(startTime == Animation.START_ON_FIRST_FRAME ?
SystemClock.uptimeMillis() : (startTime + startOffset + elapsedTime), new Transformation()) &&
- // We can't handle infinitely repeating animations in the current scheduling model,
- // so abort after one iteration.
- !(animation.getRepeatCount() == Animation.INFINITE && elapsedTime >= animation.getDuration())) {
+ // We can't handle infinitely repeating animations in the current scheduling model,
+ // so abort after one iteration.
+ !(animation.getRepeatCount() == Animation.INFINITE && elapsedTime >= animation.getDuration())) {
// Update startTime if it had a value of Animation.START_ON_FIRST_FRAME
startTime = animation.getStartTime();
elapsedTime += ShadowChoreographer.getFrameInterval() / TimeUtils.NANOS_PER_MS;
@@ -504,7 +506,7 @@ public class ShadowView {
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- protected Object getWindowId() {
+ protected WindowId getWindowId() {
return WindowIdHelper.getWindowId(this);
}
@@ -557,7 +559,7 @@ public class ShadowView {
}
public static class WindowIdHelper {
- public static Object getWindowId(ShadowView shadowView) {
+ public static WindowId getWindowId(ShadowView shadowView) {
if (shadowView.isAttachedToWindow()) {
Object attachInfo = shadowView.getAttachInfo();
if (getField(attachInfo, "mWindowId") == null) {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewAnimator.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewAnimator.java
index 4abc8bc45..41a66d229 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewAnimator.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewAnimator.java
@@ -12,12 +12,12 @@ public class ShadowViewAnimator extends ShadowViewGroup {
private int currentChild = 0;
@Implementation
- public int getDisplayedChild() {
+ protected int getDisplayedChild() {
return currentChild;
}
@Implementation
- public void setDisplayedChild(int whichChild) {
+ protected void setDisplayedChild(int whichChild) {
currentChild = whichChild;
for (int i = ((ViewGroup) realView).getChildCount() - 1; i >= 0; i--) {
View child = ((ViewGroup) realView).getChildAt(i);
@@ -26,17 +26,17 @@ public class ShadowViewAnimator extends ShadowViewGroup {
}
@Implementation
- public View getCurrentView() {
+ protected View getCurrentView() {
return ((ViewGroup) realView).getChildAt(getDisplayedChild());
}
@Implementation
- public void showNext() {
+ protected void showNext() {
setDisplayedChild((getDisplayedChild() + 1) % ((ViewGroup) realView).getChildCount());
}
@Implementation
- public void showPrevious() {
+ protected void showPrevious() {
setDisplayedChild(getDisplayedChild() == 0 ? ((ViewGroup) realView).getChildCount() - 1 : getDisplayedChild() - 1);
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewConfiguration.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewConfiguration.java
index 001c0245a..2a8a414fc 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewConfiguration.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewConfiguration.java
@@ -85,7 +85,7 @@ public class ShadowViewConfiguration {
}
@Implementation
- public static ViewConfiguration get(Context context) {
+ protected static ViewConfiguration get(Context context) {
ViewConfiguration viewConfiguration = Shadow.newInstanceOf(ViewConfiguration.class);
ShadowViewConfiguration shadowViewConfiguration = Shadow.extract(viewConfiguration);
shadowViewConfiguration.setup(context);
@@ -93,142 +93,142 @@ public class ShadowViewConfiguration {
}
@Implementation
- public static int getScrollBarSize() {
+ protected static int getScrollBarSize() {
return SCROLL_BAR_SIZE;
}
@Implementation
- public int getScaledScrollBarSize() {
+ protected int getScaledScrollBarSize() {
return scrollbarSize;
}
@Implementation
- public static int getScrollBarFadeDuration() {
+ protected static int getScrollBarFadeDuration() {
return SCROLL_BAR_FADE_DURATION;
}
@Implementation
- public static int getScrollDefaultDelay() {
+ protected static int getScrollDefaultDelay() {
return SCROLL_BAR_DEFAULT_DELAY;
}
@Implementation
- public static int getFadingEdgeLength() {
+ protected static int getFadingEdgeLength() {
return FADING_EDGE_LENGTH;
}
@Implementation
- public int getScaledFadingEdgeLength() {
+ protected int getScaledFadingEdgeLength() {
return fadingEdgeLength;
}
@Implementation
- public static int getPressedStateDuration() {
+ protected static int getPressedStateDuration() {
return PRESSED_STATE_DURATION;
}
@Implementation
- public static int getLongPressTimeout() {
+ protected static int getLongPressTimeout() {
return LONG_PRESS_TIMEOUT;
}
@Implementation
- public static int getTapTimeout() {
+ protected static int getTapTimeout() {
return TAP_TIMEOUT;
}
@Implementation
- public static int getJumpTapTimeout() {
+ protected static int getJumpTapTimeout() {
return JUMP_TAP_TIMEOUT;
}
@Implementation
- public static int getDoubleTapTimeout() {
+ protected static int getDoubleTapTimeout() {
return DOUBLE_TAP_TIMEOUT;
}
@Implementation
- public static int getEdgeSlop() {
+ protected static int getEdgeSlop() {
return EDGE_SLOP;
}
@Implementation
- public int getScaledEdgeSlop() {
+ protected int getScaledEdgeSlop() {
return edgeSlop;
}
@Implementation
- public static int getTouchSlop() {
+ protected static int getTouchSlop() {
return TOUCH_SLOP;
}
@Implementation
- public int getScaledTouchSlop() {
+ protected int getScaledTouchSlop() {
return touchSlop;
}
@Implementation
- public int getScaledPagingTouchSlop() {
+ protected int getScaledPagingTouchSlop() {
return pagingTouchSlop;
}
@Implementation
- public int getScaledDoubleTapSlop() {
+ protected int getScaledDoubleTapSlop() {
return doubleTapSlop;
}
@Implementation
- public static int getWindowTouchSlop() {
+ protected static int getWindowTouchSlop() {
return WINDOW_TOUCH_SLOP;
}
@Implementation
- public int getScaledWindowTouchSlop() {
+ protected int getScaledWindowTouchSlop() {
return windowTouchSlop;
}
@Implementation
- public static int getMinimumFlingVelocity() {
+ protected static int getMinimumFlingVelocity() {
return MINIMUM_FLING_VELOCITY;
}
@Implementation
- public int getScaledMinimumFlingVelocity() {
+ protected int getScaledMinimumFlingVelocity() {
return minimumFlingVelocity;
}
@Implementation
- public static int getMaximumFlingVelocity() {
+ protected static int getMaximumFlingVelocity() {
return MAXIMUM_FLING_VELOCITY;
}
@Implementation
- public int getScaledMaximumFlingVelocity() {
+ protected int getScaledMaximumFlingVelocity() {
return maximumFlingVelocity;
}
@Implementation
- public static int getMaximumDrawingCacheSize() {
+ protected static int getMaximumDrawingCacheSize() {
return MAXIMUM_DRAWING_CACHE_SIZE;
}
@Implementation
- public static long getZoomControlsTimeout() {
+ protected static long getZoomControlsTimeout() {
return ZOOM_CONTROLS_TIMEOUT;
}
@Implementation
- public static long getGlobalActionKeyTimeout() {
+ protected static long getGlobalActionKeyTimeout() {
return GLOBAL_ACTIONS_KEY_TIMEOUT;
}
@Implementation
- public static float getScrollFriction() {
+ protected static float getScrollFriction() {
return SCROLL_FRICTION;
}
@Implementation
- public boolean hasPermanentMenuKey() {
+ protected boolean hasPermanentMenuKey() {
return hasPermanentMenuKey;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewGroup.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewGroup.java
index 2bb6c0fe0..e1733a7cc 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewGroup.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewGroup.java
@@ -22,7 +22,7 @@ public class ShadowViewGroup extends ShadowView {
private MotionEvent interceptedTouchEvent;
@Implementation
- public void addView(final View child, final int index, final ViewGroup.LayoutParams params) {
+ protected void addView(final View child, final int index, final ViewGroup.LayoutParams params) {
ShadowLooper shadowLooper = Shadow.extract(Looper.getMainLooper());
shadowLooper.runPaused(() ->
directlyOn(realViewGroup, ViewGroup.class, "addView",
@@ -76,7 +76,7 @@ public class ShadowViewGroup extends ShadowView {
}
@Implementation
- public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+ protected void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
disallowInterceptTouchEvent = disallowIntercept;
}
@@ -96,7 +96,7 @@ public class ShadowViewGroup extends ShadowView {
}
@Implementation
- public boolean onInterceptTouchEvent(MotionEvent ev) {
+ protected boolean onInterceptTouchEvent(MotionEvent ev) {
interceptedTouchEvent = ev;
return false;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRenderNode.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRenderNode.java
new file mode 100644
index 000000000..912f28902
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRenderNode.java
@@ -0,0 +1,204 @@
+package org.robolectric.shadows;
+
+import static android.os.Build.VERSION_CODES.LOLLIPOP;
+import static android.os.Build.VERSION_CODES.P;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(className = "android.view.RenderNode", isInAndroidSdk = false, minSdk = LOLLIPOP, maxSdk = P)
+public class ShadowViewRenderNode {
+ private float alpha = 1f;
+ private float cameraDistance;
+ private boolean clipToOutline;
+ private float elevation;
+ private boolean overlappingRendering;
+ private boolean pivotExplicitlySet;
+ private float pivotX;
+ private float pivotY;
+ private float rotation;
+ private float rotationX;
+ private float rotationY;
+ private float scaleX = 1f;
+ private float scaleY = 1f;
+ private float translationX;
+ private float translationY;
+ private float translationZ;
+
+ @Implementation
+ public boolean setAlpha(float alpha) {
+ this.alpha = alpha;
+ return true;
+ }
+
+ @Implementation
+ public float getAlpha() {
+ return alpha;
+ }
+
+ @Implementation
+ public boolean setCameraDistance(float cameraDistance) {
+ this.cameraDistance = cameraDistance;
+ return true;
+ }
+
+ @Implementation
+ public float getCameraDistance() {
+ return cameraDistance;
+ }
+
+ @Implementation
+ public boolean setClipToOutline(boolean clipToOutline) {
+ this.clipToOutline = clipToOutline;
+ return true;
+ }
+
+ @Implementation
+ public boolean getClipToOutline() {
+ return clipToOutline;
+ }
+
+ @Implementation
+ public boolean setElevation(float lift) {
+ elevation = lift;
+ return true;
+ }
+
+ @Implementation
+ public float getElevation() {
+ return elevation;
+ }
+
+ @Implementation
+ public boolean setHasOverlappingRendering(boolean overlappingRendering) {
+ this.overlappingRendering = overlappingRendering;
+ return true;
+ }
+
+ @Implementation
+ public boolean hasOverlappingRendering() {
+ return overlappingRendering;
+ }
+
+ @Implementation
+ public boolean setRotation(float rotation) {
+ this.rotation = rotation;
+ return true;
+ }
+
+ @Implementation
+ public float getRotation() {
+ return rotation;
+ }
+
+ @Implementation
+ public boolean setRotationX(float rotationX) {
+ this.rotationX = rotationX;
+ return true;
+ }
+
+ @Implementation
+ public float getRotationX() {
+ return rotationX;
+ }
+
+ @Implementation
+ public boolean setRotationY(float rotationY) {
+ this.rotationY = rotationY;
+ return true;
+ }
+
+ @Implementation
+ public float getRotationY() {
+ return rotationY;
+ }
+
+ @Implementation
+ public boolean setScaleX(float scaleX) {
+ this.scaleX = scaleX;
+ return true;
+ }
+
+ @Implementation
+ public float getScaleX() {
+ return scaleX;
+ }
+
+ @Implementation
+ public boolean setScaleY(float scaleY) {
+ this.scaleY = scaleY;
+ return true;
+ }
+
+ @Implementation
+ public float getScaleY() {
+ return scaleY;
+ }
+
+ @Implementation
+ public boolean setTranslationX(float translationX) {
+ this.translationX = translationX;
+ return true;
+ }
+
+ @Implementation
+ public boolean setTranslationY(float translationY) {
+ this.translationY = translationY;
+ return true;
+ }
+
+ @Implementation
+ public boolean setTranslationZ(float translationZ) {
+ this.translationZ = translationZ;
+ return true;
+ }
+
+ @Implementation
+ public float getTranslationX() {
+ return translationX;
+ }
+
+ @Implementation
+ public float getTranslationY() {
+ return translationY;
+ }
+
+ @Implementation
+ public float getTranslationZ() {
+ return translationZ;
+ }
+
+ @Implementation
+ public boolean isPivotExplicitlySet() {
+ return pivotExplicitlySet;
+ }
+
+ @Implementation
+ public boolean setPivotX(float pivotX) {
+ this.pivotX = pivotX;
+ this.pivotExplicitlySet = true;
+ return true;
+ }
+
+ @Implementation
+ public float getPivotX() {
+ return pivotX;
+ }
+
+ @Implementation
+ public boolean setPivotY(float pivotY) {
+ this.pivotY = pivotY;
+ this.pivotExplicitlySet = true;
+ return true;
+ }
+
+ @Implementation
+ public float getPivotY() {
+ return pivotY;
+ }
+
+ @Implementation
+ protected boolean isValid() {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRootImpl.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRootImpl.java
index 5f5952b49..9638427ef 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRootImpl.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowViewRootImpl.java
@@ -10,6 +10,7 @@ import android.os.Build;
import android.os.Looper;
import android.util.MergedConfiguration;
import android.view.Display;
+import android.view.IWindowSession;
import android.view.ViewRootImpl;
import android.view.WindowManager;
import java.util.ArrayList;
@@ -27,7 +28,7 @@ public class ShadowViewRootImpl {
@RealObject private ViewRootImpl realObject;
@Implementation(maxSdk = JELLY_BEAN)
- public static Object getWindowSession(Looper mainLooper) {
+ public static IWindowSession getWindowSession(Looper mainLooper) {
return null;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVisualVoicemailSms.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVisualVoicemailSms.java
index debe0998e..17478d6dc 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVisualVoicemailSms.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVisualVoicemailSms.java
@@ -29,7 +29,7 @@ public class ShadowVisualVoicemailSms {
}
@Implementation
- public PhoneAccountHandle getPhoneAccountHandle() {
+ protected PhoneAccountHandle getPhoneAccountHandle() {
return phoneAccountHandle;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWallpaperManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWallpaperManager.java
index a8b021484..341ae0221 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWallpaperManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWallpaperManager.java
@@ -12,11 +12,11 @@ import org.robolectric.shadow.api.Shadow;
public class ShadowWallpaperManager {
@Implementation
- public static WallpaperManager getInstance(Context context) {
+ protected static WallpaperManager getInstance(Context context) {
return Shadow.newInstanceOf(WallpaperManager.class);
}
@Implementation
- public void sendWallpaperCommand(IBinder windowToken, String action, int x, int y, int z, Bundle extras) {
- }
+ protected void sendWallpaperCommand(
+ IBinder windowToken, String action, int x, int y, int z, Bundle extras) {}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebStorage.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebStorage.java
new file mode 100644
index 000000000..abfdba2ee
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebStorage.java
@@ -0,0 +1,18 @@
+package org.robolectric.shadows;
+
+import android.webkit.WebStorage;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/**
+ * Shadow of {@link WebStorage} which constructs a stub instance rather than attempting to create a
+ * full Chromium-backed instance.
+ */
+@Implements(value = WebStorage.class)
+public class ShadowWebStorage {
+
+ @Implementation
+ protected static WebStorage getInstance() {
+ return new WebStorage();
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebSyncManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebSyncManager.java
index bd7a52453..e46fd9635 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebSyncManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebSyncManager.java
@@ -8,7 +8,7 @@ public class ShadowWebSyncManager {
protected boolean synced = false;
@Implementation
- public void sync() {
+ protected void sync() {
synced = true;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebView.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebView.java
index 8a41248a4..9599e91f8 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebView.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebView.java
@@ -1,7 +1,5 @@
package org.robolectric.shadows;
-import static android.os.Build.VERSION_CODES.N_MR1;
-
import android.content.pm.PackageInfo;
import android.graphics.Bitmap;
import android.os.Build;
@@ -26,6 +24,7 @@ import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
+import org.robolectric.annotation.Resetter;
import org.robolectric.fakes.RoboWebSettings;
import org.robolectric.util.ReflectionHelpers;
@@ -36,6 +35,8 @@ public class ShadowWebView extends ShadowViewGroup {
private static final String HISTORY_KEY = "ShadowWebView.History";
+ private static PackageInfo packageInfo = null;
+
private String lastUrl;
private Map<String, String> lastAdditionalHttpHeaders;
private HashMap<String, Object> javascriptInterfaces = new HashMap<>();
@@ -314,14 +315,28 @@ public class ShadowWebView extends ShadowViewGroup {
}
@Implementation
+ protected WebBackForwardList copyBackForwardList() {
+ return new BackForwardList(history);
+ }
+
+ @Implementation
protected static String findAddress(String addr) {
return null;
}
- /** Overrides the system implementation for getting the webview package. Always returns null. */
- @Implementation(minSdk = Build.VERSION_CODES.O, maxSdk = N_MR1)
- protected static PackageInfo getCurrentWebviewPackage() {
- return null;
+ /**
+ * Overrides the system implementation for getting the WebView package.
+ *
+ * <p>Returns null by default, but this can be changed with {@code #setCurrentWebviewPackage()}.
+ */
+ @Implementation(minSdk = Build.VERSION_CODES.O)
+ protected static PackageInfo getCurrentWebViewPackage() {
+ return packageInfo;
+ }
+
+ /** Sets the value to return from {@code #getCurrentWebviewPackage()}. */
+ public static void setCurrentWebViewPackage(PackageInfo webViewPackageInfo) {
+ packageInfo = webViewPackageInfo;
}
@Implementation(minSdk = Build.VERSION_CODES.KITKAT)
@@ -381,6 +396,11 @@ public class ShadowWebView extends ShadowViewGroup {
return null;
}
+ @Resetter
+ public static void reset() {
+ packageInfo = null;
+ }
+
public static void setWebContentsDebuggingEnabled(boolean enabled) {}
public static class LoadDataWithBaseURL {
@@ -433,6 +453,10 @@ public class ShadowWebView extends ShadowViewGroup {
@Override
public HistoryItem getCurrentItem() {
+ if (history.isEmpty()) {
+ return null;
+ }
+
return new HistoryItem(history.get(getCurrentIndex()));
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebViewDatabase.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebViewDatabase.java
index c8b401fe5..91b2430da 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebViewDatabase.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebViewDatabase.java
@@ -10,7 +10,7 @@ import org.robolectric.shadow.api.Shadow;
public class ShadowWebViewDatabase {
@Implementation
- public static WebViewDatabase getInstance(Context ignored) {
+ protected static WebViewDatabase getInstance(Context ignored) {
return Shadow.newInstanceOf(WebViewDatabase.class);
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiManager.java
index bcb3cc31b..92484a38d 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiManager.java
@@ -3,6 +3,7 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
import static android.os.Build.VERSION_CODES.KITKAT;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
+import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.net.ConnectivityManager;
@@ -18,10 +19,12 @@ import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.util.ReflectionHelpers;
@@ -44,22 +47,24 @@ public class ShadowWifiManager {
private boolean isScanAlwaysAvailable = true;
private boolean startScanSucceeds = true;
private boolean is5GHzBandSupported = false;
+ private AtomicInteger activeLockCount = new AtomicInteger(0);
+ @RealObject WifiManager wifiManager;
@Implementation
- public boolean setWifiEnabled(boolean wifiEnabled) {
+ protected boolean setWifiEnabled(boolean wifiEnabled) {
checkAccessWifiStatePermission();
this.wifiEnabled = wifiEnabled;
return true;
}
@Implementation
- public boolean isWifiEnabled() {
+ protected boolean isWifiEnabled() {
checkAccessWifiStatePermission();
return wifiEnabled;
}
@Implementation
- public int getWifiState() {
+ protected int getWifiState() {
if (isWifiEnabled()) {
return WifiManager.WIFI_STATE_ENABLED;
} else {
@@ -68,7 +73,7 @@ public class ShadowWifiManager {
}
@Implementation
- public WifiInfo getConnectionInfo() {
+ protected WifiInfo getConnectionInfo() {
checkAccessWifiStatePermission();
if (wifiInfo == null) {
wifiInfo = ReflectionHelpers.callConstructor(WifiInfo.class);
@@ -77,7 +82,7 @@ public class ShadowWifiManager {
}
@Implementation(minSdk = LOLLIPOP)
- public boolean is5GHzBandSupported() {
+ protected boolean is5GHzBandSupported() {
return is5GHzBandSupported;
}
@@ -99,12 +104,12 @@ public class ShadowWifiManager {
}
@Implementation
- public List<ScanResult> getScanResults() {
+ protected List<ScanResult> getScanResults() {
return scanResults;
}
@Implementation
- public List<WifiConfiguration> getConfiguredNetworks() {
+ protected List<WifiConfiguration> getConfiguredNetworks() {
final ArrayList<WifiConfiguration> wifiConfigurations = new ArrayList<>();
for (WifiConfiguration wifiConfiguration : networkIdToConfiguredNetworks.values()) {
wifiConfigurations.add(wifiConfiguration);
@@ -113,12 +118,12 @@ public class ShadowWifiManager {
}
@Implementation(minSdk = LOLLIPOP)
- public List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
+ protected List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
return getConfiguredNetworks();
}
@Implementation
- public int addNetwork(WifiConfiguration config) {
+ protected int addNetwork(WifiConfiguration config) {
int networkId = networkIdToConfiguredNetworks.size();
config.networkId = -1;
networkIdToConfiguredNetworks.put(networkId, makeCopy(config, networkId));
@@ -126,13 +131,13 @@ public class ShadowWifiManager {
}
@Implementation
- public boolean removeNetwork(int netId) {
+ protected boolean removeNetwork(int netId) {
networkIdToConfiguredNetworks.remove(netId);
return true;
}
@Implementation
- public int updateNetwork(WifiConfiguration config) {
+ protected int updateNetwork(WifiConfiguration config) {
if (config == null || config.networkId < 0) {
return -1;
}
@@ -141,29 +146,38 @@ public class ShadowWifiManager {
}
@Implementation
- public boolean saveConfiguration() {
+ protected boolean saveConfiguration() {
wasSaved = true;
return true;
}
@Implementation
- public boolean enableNetwork(int netId, boolean disableOthers) {
+ protected boolean enableNetwork(int netId, boolean disableOthers) {
lastEnabledNetwork = new Pair<>(netId, disableOthers);
return true;
}
@Implementation
- public WifiManager.WifiLock createWifiLock(int lockType, java.lang.String tag) {
- return ReflectionHelpers.callConstructor(WifiManager.WifiLock.class);
+ protected WifiManager.WifiLock createWifiLock(int lockType, String tag) {
+ WifiManager.WifiLock wifiLock = ReflectionHelpers.callConstructor(WifiManager.WifiLock.class);
+ shadowOf(wifiLock).setWifiManager(wifiManager);
+ return wifiLock;
}
@Implementation
- public WifiManager.WifiLock createWifiLock(java.lang.String tag) {
+ protected WifiManager.WifiLock createWifiLock(String tag) {
return createWifiLock(WifiManager.WIFI_MODE_FULL, tag);
}
@Implementation
- public static int calculateSignalLevel(int rssi, int numLevels) {
+ protected MulticastLock createMulticastLock(String tag) {
+ MulticastLock multicastLock = ReflectionHelpers.callConstructor(MulticastLock.class);
+ shadowOf(multicastLock).setWifiManager(wifiManager);
+ return multicastLock;
+ }
+
+ @Implementation
+ protected static int calculateSignalLevel(int rssi, int numLevels) {
return (int) (sSignalLevelInPercent * (numLevels - 1));
}
@@ -177,17 +191,17 @@ public class ShadowWifiManager {
* was never called.
*/
@Implementation
- public boolean startScan() {
+ protected boolean startScan() {
return startScanSucceeds;
}
@Implementation
- public DhcpInfo getDhcpInfo() {
+ protected DhcpInfo getDhcpInfo() {
return dhcpInfo;
}
@Implementation(minSdk = JELLY_BEAN_MR2)
- public boolean isScanAlwaysAvailable() {
+ protected boolean isScanAlwaysAvailable() {
return isScanAlwaysAvailable;
}
@@ -222,7 +236,7 @@ public class ShadowWifiManager {
true /* isConnected */);
ShadowConnectivityManager connectivityManager =
Shadow.extract(
- RuntimeEnvironment.application.getSystemService(Context.CONNECTIVITY_SERVICE));
+ RuntimeEnvironment.application.getSystemService(Context.CONNECTIVITY_SERVICE));
connectivityManager.setActiveNetworkInfo(networkInfo);
if (listener != null) {
@@ -230,8 +244,18 @@ public class ShadowWifiManager {
}
}
+ @HiddenApi
+ @Implementation(minSdk = KITKAT)
+ protected void connect(int networkId, WifiManager.ActionListener listener) {
+ WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.networkId = networkId;
+ wifiConfiguration.SSID = "";
+ wifiConfiguration.BSSID = "";
+ connect(wifiConfiguration, listener);
+ }
+
private static boolean isQuoted(String str) {
- if (str.length() < 2) {
+ if (str == null || str.length() < 2) {
return false;
}
@@ -284,6 +308,11 @@ public class ShadowWifiManager {
return lastEnabledNetwork;
}
+ /** Returns the number of WifiLocks and MulticastLocks that are currently acquired. */
+ public int getActiveLockCount() {
+ return activeLockCount.get();
+ }
+
public boolean wasConfigurationSaved() {
return wasSaved;
}
@@ -314,10 +343,18 @@ public class ShadowWifiManager {
private int refCount;
private boolean refCounted = true;
private boolean locked;
+ private WifiManager wifiManager;
public static final int MAX_ACTIVE_LOCKS = 50;
+ private void setWifiManager(WifiManager wifiManager) {
+ this.wifiManager = wifiManager;
+ }
+
@Implementation
- public synchronized void acquire() {
+ protected synchronized void acquire() {
+ if (wifiManager != null) {
+ shadowOf(wifiManager).activeLockCount.getAndIncrement();
+ }
if (refCounted) {
if (++refCount >= MAX_ACTIVE_LOCKS) throw new UnsupportedOperationException("Exceeded maximum number of wifi locks");
} else {
@@ -326,7 +363,10 @@ public class ShadowWifiManager {
}
@Implementation
- public synchronized void release() {
+ protected synchronized void release() {
+ if (wifiManager != null) {
+ shadowOf(wifiManager).activeLockCount.getAndDecrement();
+ }
if (refCounted) {
if (--refCount < 0) throw new RuntimeException("WifiLock under-locked");
} else {
@@ -335,12 +375,12 @@ public class ShadowWifiManager {
}
@Implementation
- public synchronized boolean isHeld() {
+ protected synchronized boolean isHeld() {
return refCounted ? refCount > 0 : locked;
}
@Implementation
- public void setReferenceCounted(boolean refCounted) {
+ protected void setReferenceCounted(boolean refCounted) {
this.refCounted = refCounted;
}
}
@@ -351,9 +391,17 @@ public class ShadowWifiManager {
private boolean refCounted = true;
private boolean locked;
static final int MAX_ACTIVE_LOCKS = 50;
+ private WifiManager wifiManager;
+
+ private void setWifiManager(WifiManager wifiManager) {
+ this.wifiManager = wifiManager;
+ }
@Implementation
protected void acquire() {
+ if (wifiManager != null) {
+ shadowOf(wifiManager).activeLockCount.getAndIncrement();
+ }
if (refCounted) {
if (++refCount >= MAX_ACTIVE_LOCKS) throw new UnsupportedOperationException("Exceeded maximum number of wifi locks");
} else {
@@ -363,6 +411,9 @@ public class ShadowWifiManager {
@Implementation
protected synchronized void release() {
+ if (wifiManager != null) {
+ shadowOf(wifiManager).activeLockCount.getAndDecrement();
+ }
if (refCounted) {
if (--refCount < 0) throw new RuntimeException("WifiLock under-locked");
} else {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiP2pManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiP2pManager.java
index 9a50f8582..54e6b2800 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiP2pManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiP2pManager.java
@@ -41,7 +41,7 @@ public class ShadowWifiP2pManager {
}
@Implementation(minSdk = KITKAT)
- public void setWifiP2pChannels(
+ protected void setWifiP2pChannels(
Channel c, int listeningChannel, int operatingChannel, ActionListener al) {
Preconditions.checkNotNull(c);
Preconditions.checkNotNull(al);
@@ -50,13 +50,14 @@ public class ShadowWifiP2pManager {
}
@Implementation
- public Channel initialize(Context context, Looper looper, WifiP2pManager.ChannelListener listener) {
+ protected Channel initialize(
+ Context context, Looper looper, WifiP2pManager.ChannelListener listener) {
handler = new Handler(looper);
return ReflectionHelpers.newInstance(Channel.class);
}
@Implementation
- public void createGroup(Channel c, ActionListener al) {
+ protected void createGroup(Channel c, ActionListener al) {
postActionListener(al);
}
@@ -79,7 +80,7 @@ public class ShadowWifiP2pManager {
}
@Implementation
- public void requestGroupInfo(final Channel c, final WifiP2pManager.GroupInfoListener gl) {
+ protected void requestGroupInfo(final Channel c, final WifiP2pManager.GroupInfoListener gl) {
if (gl == null) {
return;
}
@@ -93,7 +94,7 @@ public class ShadowWifiP2pManager {
}
@Implementation
- public void removeGroup(Channel c, ActionListener al) {
+ protected void removeGroup(Channel c, ActionListener al) {
postActionListener(al);
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindow.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindow.java
index 52f0954b2..29be74859 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindow.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindow.java
@@ -34,13 +34,13 @@ public class ShadowWindow {
}
@Implementation
- public void setFlags(int flags, int mask) {
+ protected void setFlags(int flags, int mask) {
this.flags = (this.flags & ~mask) | (flags & mask);
directlyOn(realWindow, Window.class, "setFlags", ClassParameter.from(int.class, flags), ClassParameter.from(int.class, mask));
}
@Implementation
- public void setSoftInputMode(int softInputMode) {
+ protected void setSoftInputMode(int softInputMode) {
this.softInputMode = softInputMode;
directlyOn(realWindow, Window.class, "setSoftInputMode", ClassParameter.from(int.class, softInputMode));
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java
index e7f78c538..a6aeaf2a9 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java
@@ -10,12 +10,14 @@ import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;
import org.robolectric.util.ReflectionHelpers;
-@Implements(value = WindowManagerGlobal.class, isInAndroidSdk = false, minSdk = JELLY_BEAN_MR1)
+@Implements(value = WindowManagerGlobal.class, isInAndroidSdk = false,
+ minSdk = JELLY_BEAN_MR1, looseSignatures = true)
public class ShadowWindowManagerGlobal {
@Resetter
public static void reset() {
- ReflectionHelpers.setStaticField(WindowManagerGlobal.class, "sDefaultWindowManager", null);
+ ReflectionHelpers.setStaticField(
+ WindowManagerGlobal.class, "sDefaultWindowManager", null);
}
@Implementation(minSdk = JELLY_BEAN_MR2)
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerImpl.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerImpl.java
index 7ff5e210f..f324b5ecf 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerImpl.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerImpl.java
@@ -44,11 +44,11 @@ public class ShadowWindowManagerImpl extends ShadowWindowManager {
@RealObject
WindowManagerImpl realObject;
- private static Multimap<Display, View> views = ArrayListMultimap.create();
+ private static final Multimap<Integer, View> views = ArrayListMultimap.create();
@Implementation
public void addView(View view, android.view.ViewGroup.LayoutParams layoutParams) {
- views.put(realObject.getDefaultDisplay(), view);
+ views.put(realObject.getDefaultDisplay().getDisplayId(), view);
// views.add(view);
directlyOn(
realObject,
@@ -60,13 +60,13 @@ public class ShadowWindowManagerImpl extends ShadowWindowManager {
@Implementation
public void removeView(View view) {
- views.remove(realObject.getDefaultDisplay(), view);
+ views.remove(realObject.getDefaultDisplay().getDisplayId(), view);
directlyOn(realObject, WindowManagerImpl.class, "removeView",
ClassParameter.from(View.class, view));
}
public List<View> getViews() {
- return ImmutableList.copyOf(views.get(realObject.getDefaultDisplay()));
+ return ImmutableList.copyOf(views.get(realObject.getDefaultDisplay().getDisplayId()));
}
@Implementation(maxSdk = JELLY_BEAN)
@@ -81,7 +81,7 @@ public class ShadowWindowManagerImpl extends ShadowWindowManager {
@Implements(className = "android.view.WindowManagerImpl$CompatModeWrapper", maxSdk = JELLY_BEAN)
public static class ShadowCompatModeWrapper {
@Implementation(maxSdk = JELLY_BEAN)
- public Display getDefaultDisplay() {
+ protected Display getDefaultDisplay() {
return defaultDisplayJB;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowZoomButtonsController.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowZoomButtonsController.java
index 3be32d012..2642083aa 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowZoomButtonsController.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowZoomButtonsController.java
@@ -11,10 +11,10 @@ public class ShadowZoomButtonsController {
private ZoomButtonsController.OnZoomListener listener;
@Implementation
- public void __constructor__(View ownerView) {}
+ protected void __constructor__(View ownerView) {}
@Implementation
- public void setOnZoomListener(ZoomButtonsController.OnZoomListener listener) {
+ protected void setOnZoomListener(ZoomButtonsController.OnZoomListener listener) {
this.listener = listener;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/StorageVolumeBuilder.java b/shadows/framework/src/main/java/org/robolectric/shadows/StorageVolumeBuilder.java
new file mode 100644
index 000000000..b31eae199
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/StorageVolumeBuilder.java
@@ -0,0 +1,101 @@
+package org.robolectric.shadows;
+
+import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
+
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
+import android.os.UserHandle;
+import android.os.storage.StorageVolume;
+import java.io.File;
+import org.robolectric.util.ReflectionHelpers;
+
+/** Class to build {@link StorageVolume} */
+public final class StorageVolumeBuilder {
+
+ private String id;
+ private int storageId = 0;
+ private File path;
+ private String description;
+ private boolean primary = true;
+ private boolean removable = false;
+ private boolean emulated = false;
+ private long mtpReserveSize = 00L;
+ private boolean allowMassStorage = false;
+ private long maxFileSize = 100L;
+ private UserHandle owner;
+ private String fsUuid = "4213-3435:";
+ private String state;
+
+ public StorageVolumeBuilder(
+ String id, File path, String description, UserHandle owner, String state) {
+ this.id = id;
+ this.path = path;
+ this.description = description;
+ this.owner = owner;
+ this.state = state;
+ }
+
+ void setStorageId(int storageId) {
+ this.storageId = storageId;
+ }
+
+ void setIsPrimary(boolean isPrimary) {
+ this.primary = isPrimary;
+ }
+
+ void setIsRemovable(boolean isRemovable) {
+ this.removable = isRemovable;
+ }
+
+ void setIsEmulated(boolean isEmulated) {
+ this.emulated = isEmulated;
+ }
+
+ void setMtpReserveSize(long mtpReserveSize) {
+ this.mtpReserveSize = mtpReserveSize;
+ }
+
+ void setAllowMassStorage(boolean allowMassStorage) {
+ this.allowMassStorage = allowMassStorage;
+ }
+
+ void setMaxFileSize(long maxFileSize) {
+ this.maxFileSize = maxFileSize;
+ }
+
+ public StorageVolume build() throws IllegalStateException {
+ if (Build.VERSION.SDK_INT >= VERSION_CODES.N && Build.VERSION.SDK_INT < VERSION_CODES.P) {
+ return ReflectionHelpers.callConstructor(
+ StorageVolume.class,
+ from(String.class, id), // String id,
+ from(int.class, storageId), // int storageId
+ from(File.class, path), // File path,
+ from(String.class, description), // String description
+ from(boolean.class, primary), // boolean primary,
+ from(boolean.class, removable), // boolean removable,
+ from(boolean.class, emulated), // boolean emulated,
+ from(long.class, mtpReserveSize), // long mtpReserveSize,
+ from(boolean.class, allowMassStorage),
+ from(long.class, maxFileSize), // long maxFileSize,
+ from(UserHandle.class, owner), // UserHandle owner,
+ from(String.class, fsUuid), // String fsUuid,
+ from(String.class, state)); // String state
+ } else if (Build.VERSION.SDK_INT >= VERSION_CODES.P) {
+ return ReflectionHelpers.callConstructor(
+ StorageVolume.class,
+ from(String.class, id), // String id,
+ from(File.class, path), // File path,
+ from(File.class, path), // File internalPath
+ from(String.class, description), // String description
+ from(boolean.class, primary), // boolean primary,
+ from(boolean.class, removable), // boolean removable,
+ from(boolean.class, emulated), // boolean emulated,
+ from(boolean.class, allowMassStorage), // boolean allowMassStorage,
+ from(long.class, maxFileSize), // long maxFileSize,
+ from(UserHandle.class, owner), // UserHandle owner,
+ from(String.class, fsUuid), // String fsUuid,
+ from(String.class, state)); // String state
+ }
+ throw new IllegalStateException("StorageVolume hidden constructor not found");
+ }
+}
diff --git a/shadows/httpclient/build.gradle b/shadows/httpclient/build.gradle
index 07bd97389..8ace567b5 100644
--- a/shadows/httpclient/build.gradle
+++ b/shadows/httpclient/build.gradle
@@ -1,7 +1,3 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
@@ -17,19 +13,16 @@ configurations {
}
dependencies {
- // Project dependencies
compileOnly project(":shadows:framework")
- // Compile dependencies
earlyRuntime "org.apache.httpcomponents:httpcore:4.0.1"
- compile "org.apache.httpcomponents:httpclient:4.0.3"
+ api "org.apache.httpcomponents:httpclient:4.0.3"
compileOnly(AndroidSdk.LOLLIPOP_MR1.coordinates) { force = true }
- // Testing dependencies
- testCompile project(":robolectric")
- testCompile "junit:junit:4.12"
- testCompile "com.google.truth:truth:0.39"
- testCompile "org.mockito:mockito-core:2.5.4"
+ testImplementation project(":robolectric")
+ testImplementation "junit:junit:4.12"
+ testImplementation "com.google.truth:truth:0.42"
+ testImplementation "org.mockito:mockito-core:2.5.4"
testRuntime AndroidSdk.LOLLIPOP_MR1.coordinates
}
diff --git a/shadows/httpclient/src/main/java/org/robolectric/shadows/ShadowAndroidHttpClient.java b/shadows/httpclient/src/main/java/org/robolectric/shadows/ShadowAndroidHttpClient.java
index d2c9601d6..3da6bd7f4 100644
--- a/shadows/httpclient/src/main/java/org/robolectric/shadows/ShadowAndroidHttpClient.java
+++ b/shadows/httpclient/src/main/java/org/robolectric/shadows/ShadowAndroidHttpClient.java
@@ -26,62 +26,80 @@ public class ShadowAndroidHttpClient {
private HttpClient httpClient = new DefaultHttpClient();
@Implementation
- public static AndroidHttpClient newInstance(String userAgent) {
+ protected static AndroidHttpClient newInstance(String userAgent) {
return ReflectionHelpers.callConstructor(AndroidHttpClient.class);
}
@Implementation
- public static AndroidHttpClient newInstance(String userAgent, Context context) {
+ protected static AndroidHttpClient newInstance(String userAgent, Context context) {
return ReflectionHelpers.callConstructor(AndroidHttpClient.class);
}
@Implementation
- public HttpParams getParams() {
+ protected HttpParams getParams() {
return httpClient.getParams();
}
@Implementation
- public ClientConnectionManager getConnectionManager() {
+ protected ClientConnectionManager getConnectionManager() {
return httpClient.getConnectionManager();
}
@Implementation
- public HttpResponse execute(HttpUriRequest httpUriRequest) throws IOException, ClientProtocolException {
+ protected HttpResponse execute(HttpUriRequest httpUriRequest)
+ throws IOException, ClientProtocolException {
return httpClient.execute(httpUriRequest);
}
@Implementation
- public HttpResponse execute(HttpUriRequest httpUriRequest, HttpContext httpContext) throws IOException, ClientProtocolException {
+ protected HttpResponse execute(HttpUriRequest httpUriRequest, HttpContext httpContext)
+ throws IOException, ClientProtocolException {
return httpClient.execute(httpUriRequest, httpContext);
}
@Implementation
- public HttpResponse execute(HttpHost httpHost, HttpRequest httpRequest) throws IOException, ClientProtocolException {
+ protected HttpResponse execute(HttpHost httpHost, HttpRequest httpRequest)
+ throws IOException, ClientProtocolException {
return httpClient.execute(httpHost, httpRequest);
}
@Implementation
- public HttpResponse execute(HttpHost httpHost, HttpRequest httpRequest, HttpContext httpContext) throws IOException, ClientProtocolException {
+ protected HttpResponse execute(
+ HttpHost httpHost, HttpRequest httpRequest, HttpContext httpContext)
+ throws IOException, ClientProtocolException {
return httpClient.execute(httpHost, httpRequest, httpContext);
}
@Implementation
- public <T> T execute(HttpUriRequest httpUriRequest, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
+ protected <T> T execute(
+ HttpUriRequest httpUriRequest, ResponseHandler<? extends T> responseHandler)
+ throws IOException, ClientProtocolException {
return httpClient.execute(httpUriRequest, responseHandler);
}
@Implementation
- public <T> T execute(HttpUriRequest httpUriRequest, ResponseHandler<? extends T> responseHandler, HttpContext httpContext) throws IOException, ClientProtocolException {
+ protected <T> T execute(
+ HttpUriRequest httpUriRequest,
+ ResponseHandler<? extends T> responseHandler,
+ HttpContext httpContext)
+ throws IOException, ClientProtocolException {
return httpClient.execute(httpUriRequest, responseHandler, httpContext);
}
@Implementation
- public <T> T execute(HttpHost httpHost, HttpRequest httpRequest, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
+ protected <T> T execute(
+ HttpHost httpHost, HttpRequest httpRequest, ResponseHandler<? extends T> responseHandler)
+ throws IOException, ClientProtocolException {
return httpClient.execute(httpHost, httpRequest, responseHandler);
}
@Implementation
- public <T> T execute(HttpHost httpHost, HttpRequest httpRequest, ResponseHandler<? extends T> responseHandler, HttpContext httpContext) throws IOException, ClientProtocolException {
+ protected <T> T execute(
+ HttpHost httpHost,
+ HttpRequest httpRequest,
+ ResponseHandler<? extends T> responseHandler,
+ HttpContext httpContext)
+ throws IOException, ClientProtocolException {
return httpClient.execute(httpHost, httpRequest, responseHandler, httpContext);
}
} \ No newline at end of file
diff --git a/shadows/httpclient/src/main/java/org/robolectric/shadows/httpclient/ShadowDefaultRequestDirector.java b/shadows/httpclient/src/main/java/org/robolectric/shadows/httpclient/ShadowDefaultRequestDirector.java
index dadad5040..580eae406 100644
--- a/shadows/httpclient/src/main/java/org/robolectric/shadows/httpclient/ShadowDefaultRequestDirector.java
+++ b/shadows/httpclient/src/main/java/org/robolectric/shadows/httpclient/ShadowDefaultRequestDirector.java
@@ -54,7 +54,7 @@ public class ShadowDefaultRequestDirector {
org.robolectric.shadows.httpclient.DefaultRequestDirector redirector;
@Implementation
- public void __constructor__(
+ protected void __constructor__(
Log log,
HttpRequestExecutor requestExec,
ClientConnectionManager conman,
@@ -104,7 +104,7 @@ public class ShadowDefaultRequestDirector {
}
@Implementation
- public void __constructor__(
+ protected void __constructor__(
HttpRequestExecutor requestExec,
ClientConnectionManager conman,
ConnectionReuseStrategy reustrat,
@@ -163,7 +163,9 @@ public class ShadowDefaultRequestDirector {
}
@Implementation
- public HttpResponse execute(HttpHost httpHost, HttpRequest httpRequest, HttpContext httpContext) throws HttpException, IOException {
+ protected HttpResponse execute(
+ HttpHost httpHost, HttpRequest httpRequest, HttpContext httpContext)
+ throws HttpException, IOException {
if (FakeHttp.getFakeHttpLayer().isInterceptingHttpRequests()) {
return FakeHttp.getFakeHttpLayer().emulateRequest(httpHost, httpRequest, httpContext, realObject);
} else {
diff --git a/shadows/httpclient/src/test/java/org/robolectric/util/TestRunnerWithManifest.java b/shadows/httpclient/src/test/java/org/robolectric/util/TestRunnerWithManifest.java
index 9a3ae2798..9ed0b2f6e 100644
--- a/shadows/httpclient/src/test/java/org/robolectric/util/TestRunnerWithManifest.java
+++ b/shadows/httpclient/src/test/java/org/robolectric/util/TestRunnerWithManifest.java
@@ -3,10 +3,12 @@ package org.robolectric.util;
import java.io.File;
import java.net.URI;
import java.net.URL;
+import java.util.Collections;
import org.junit.runners.model.InitializationError;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-import org.robolectric.manifest.AndroidManifest;
+import org.robolectric.internal.ManifestFactory;
+import org.robolectric.internal.ManifestIdentifier;
import org.robolectric.res.Fs;
import org.robolectric.res.FsFile;
@@ -36,7 +38,13 @@ public class TestRunnerWithManifest extends RobolectricTestRunner {
}
@Override
- protected AndroidManifest getAppManifest(Config config) {
- return new AndroidManifest(resourceFile("AndroidManifest.xml"), resourceFile("res"), resourceFile("assets"));
+ protected ManifestFactory getManifestFactory(Config config) {
+ return c -> new ManifestIdentifier(
+ "org.robolectric",
+ resourceFile("AndroidManifest.xml"),
+ resourceFile("res"),
+ resourceFile("assets"),
+ Collections.emptyList()
+ );
}
}
diff --git a/shadows/multidex/build.gradle b/shadows/multidex/build.gradle
index 66fd25e67..141300477 100644
--- a/shadows/multidex/build.gradle
+++ b/shadows/multidex/build.gradle
@@ -1,7 +1,3 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
@@ -19,5 +15,5 @@ dependencies {
compileOnly AndroidSdk.MAX_SDK.coordinates
- testCompile project(":robolectric")
+ testImplementation project(":robolectric")
}
diff --git a/shadows/playservices/build.gradle b/shadows/playservices/build.gradle
index 6418644ea..c843b7c37 100644
--- a/shadows/playservices/build.gradle
+++ b/shadows/playservices/build.gradle
@@ -1,7 +1,3 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
@@ -21,11 +17,10 @@ dependencies {
compileOnly AndroidSdk.MAX_SDK.coordinates
- // Testing dependencies
- testCompile project(":robolectric")
- testCompile "junit:junit:4.12"
- testCompile "com.google.truth:truth:0.39"
- testCompile "org.mockito:mockito-core:2.5.4"
+ testImplementation project(":robolectric")
+ testImplementation "junit:junit:4.12"
+ testImplementation "com.google.truth:truth:0.42"
+ testImplementation "org.mockito:mockito-core:2.5.4"
testRuntime "com.android.support:support-fragment:26.0.1"
testRuntime "com.google.android.gms:play-services-base:8.4.0"
testRuntime "com.google.android.gms:play-services-basement:8.4.0"
diff --git a/shadows/supportv4/build.gradle b/shadows/supportv4/build.gradle
index 3a6978eeb..e0c276045 100644
--- a/shadows/supportv4/build.gradle
+++ b/shadows/supportv4/build.gradle
@@ -1,7 +1,3 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
@@ -17,11 +13,9 @@ configurations {
}
dependencies {
- // Project dependencies
compileOnly project(":robolectric")
compileOnly project(":shadows:framework")
- // Compile dependencies
compileOnly AndroidSdk.MAX_SDK.coordinates
compileOnly "com.android.support:support-annotations:26.0.1"
compileOnly "com.android.support:support-v4:26.0.1"
@@ -31,12 +25,11 @@ dependencies {
compileOnly "com.android.support:support-fragment:26.0.1"
compileOnly "com.android.support:support-media-compat:26.0.1"
- // Testing dependencies
- testCompile project(":robolectric")
- testCompile "junit:junit:4.12"
- testCompile "org.hamcrest:hamcrest-junit:2.0.0.0"
- testCompile "com.google.truth:truth:0.39"
- testCompile "org.mockito:mockito-core:2.5.4"
+ testImplementation project(":robolectric")
+ testImplementation "junit:junit:4.12"
+ testImplementation "org.hamcrest:hamcrest-junit:2.0.0.0"
+ testImplementation "com.google.truth:truth:0.42"
+ testImplementation "org.mockito:mockito-core:2.5.4"
earlyTestRuntime "org.hamcrest:hamcrest-junit:2.0.0.0"
testRuntime AndroidSdk.MAX_SDK.coordinates
diff --git a/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowAsyncTaskLoader.java b/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowAsyncTaskLoader.java
index 3403bbe6a..8d01034e4 100644
--- a/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowAsyncTaskLoader.java
+++ b/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowAsyncTaskLoader.java
@@ -16,12 +16,12 @@ public class ShadowAsyncTaskLoader<D> {
private BackgroundWorker worker;
@Implementation
- public void __constructor__(Context context) {
+ protected void __constructor__(Context context) {
worker = new BackgroundWorker();
}
@Implementation
- public void onForceLoad() {
+ protected void onForceLoad() {
FutureTask<D> future = new FutureTask<D>(worker) {
@Override protected void done() {
try {
diff --git a/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowDrawerLayout.java b/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowDrawerLayout.java
index b687e72e6..261671b45 100644
--- a/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowDrawerLayout.java
+++ b/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowDrawerLayout.java
@@ -15,7 +15,7 @@ public class ShadowDrawerLayout extends ShadowViewGroup {
private DrawerLayout.DrawerListener drawerListener;
@Implementation
- public void setDrawerListener(DrawerLayout.DrawerListener drawerListener) {
+ protected void setDrawerListener(DrawerLayout.DrawerListener drawerListener) {
this.drawerListener = drawerListener;
directlyOn(realDrawerLayout, DrawerLayout.class).setDrawerListener(drawerListener);
}
@@ -24,19 +24,15 @@ public class ShadowDrawerLayout extends ShadowViewGroup {
return drawerListener;
}
- /**
- * Drawer animations are disabled in unit tests.
- */
+ /** Drawer animations are disabled in unit tests. */
@Implementation
- public void openDrawer(View drawerView, boolean animate) {
+ protected void openDrawer(View drawerView, boolean animate) {
directlyOn(realDrawerLayout, DrawerLayout.class).openDrawer(drawerView, false);
}
- /**
- * Drawer animations are disabled in unit tests.
- */
+ /** Drawer animations are disabled in unit tests. */
@Implementation
- public void closeDrawer(View drawerView, boolean animate) {
+ protected void closeDrawer(View drawerView, boolean animate) {
directlyOn(realDrawerLayout, DrawerLayout.class).closeDrawer(drawerView, false);
}
}
diff --git a/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowLocalBroadcastManager.java b/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowLocalBroadcastManager.java
index dda0d6ef7..5a97abc46 100644
--- a/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowLocalBroadcastManager.java
+++ b/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowLocalBroadcastManager.java
@@ -23,7 +23,7 @@ public class ShadowLocalBroadcastManager {
private final List<Wrapper> registeredReceivers = new ArrayList<>();
@Implementation
- public static LocalBroadcastManager getInstance(final Context context) {
+ protected static LocalBroadcastManager getInstance(final Context context) {
return ShadowApplication.getInstance().getSingleton(LocalBroadcastManager.class, new Provider<LocalBroadcastManager>() {
@Override
public LocalBroadcastManager get() {
@@ -33,12 +33,12 @@ public class ShadowLocalBroadcastManager {
}
@Implementation
- public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ protected void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
registeredReceivers.add(new Wrapper(receiver, filter));
}
@Implementation
- public void unregisterReceiver(BroadcastReceiver receiver) {
+ protected void unregisterReceiver(BroadcastReceiver receiver) {
Iterator<Wrapper> iterator = registeredReceivers.iterator();
while (iterator.hasNext()) {
Wrapper wrapper = iterator.next();
@@ -49,7 +49,7 @@ public class ShadowLocalBroadcastManager {
}
@Implementation
- public boolean sendBroadcast(Intent intent) {
+ protected boolean sendBroadcast(Intent intent) {
boolean sent = false;
sentBroadcastIntents.add(intent);
List<Wrapper> copy = new ArrayList<>();
diff --git a/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowSwipeRefreshLayout.java b/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowSwipeRefreshLayout.java
index be0a10099..b9d559663 100644
--- a/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowSwipeRefreshLayout.java
+++ b/shadows/supportv4/src/main/java/org/robolectric/shadows/support/v4/ShadowSwipeRefreshLayout.java
@@ -14,7 +14,7 @@ public class ShadowSwipeRefreshLayout extends ShadowViewGroup {
private OnRefreshListener listener;
@Implementation
- public void setOnRefreshListener(OnRefreshListener listener) {
+ protected void setOnRefreshListener(OnRefreshListener listener) {
this.listener = listener;
Shadow.directlyOn(realObject, SwipeRefreshLayout.class).setOnRefreshListener(listener);
}
diff --git a/shadows/supportv4/src/test/java/org/robolectric/util/TestRunnerWithManifest.java b/shadows/supportv4/src/test/java/org/robolectric/util/TestRunnerWithManifest.java
index 9a3ae2798..9ed0b2f6e 100644
--- a/shadows/supportv4/src/test/java/org/robolectric/util/TestRunnerWithManifest.java
+++ b/shadows/supportv4/src/test/java/org/robolectric/util/TestRunnerWithManifest.java
@@ -3,10 +3,12 @@ package org.robolectric.util;
import java.io.File;
import java.net.URI;
import java.net.URL;
+import java.util.Collections;
import org.junit.runners.model.InitializationError;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-import org.robolectric.manifest.AndroidManifest;
+import org.robolectric.internal.ManifestFactory;
+import org.robolectric.internal.ManifestIdentifier;
import org.robolectric.res.Fs;
import org.robolectric.res.FsFile;
@@ -36,7 +38,13 @@ public class TestRunnerWithManifest extends RobolectricTestRunner {
}
@Override
- protected AndroidManifest getAppManifest(Config config) {
- return new AndroidManifest(resourceFile("AndroidManifest.xml"), resourceFile("res"), resourceFile("assets"));
+ protected ManifestFactory getManifestFactory(Config config) {
+ return c -> new ManifestIdentifier(
+ "org.robolectric",
+ resourceFile("AndroidManifest.xml"),
+ resourceFile("res"),
+ resourceFile("assets"),
+ Collections.emptyList()
+ );
}
}
diff --git a/testapp/build.gradle b/testapp/build.gradle
index 85ed6e596..92279db5d 100644
--- a/testapp/build.gradle
+++ b/testapp/build.gradle
@@ -17,7 +17,3 @@ android {
abortOnError false
}
}
-
-dependencies {
- implementation fileTree(dir: 'libs', include: ['*.jar'])
-}
diff --git a/testapp/src/main/AndroidManifest.xml b/testapp/src/main/AndroidManifest.xml
index 41187d199..ae269f867 100644
--- a/testapp/src/main/AndroidManifest.xml
+++ b/testapp/src/main/AndroidManifest.xml
@@ -3,9 +3,11 @@
package="org.robolectric"
android:versionCode="123"
android:versionName="aVersionName">
- <uses-sdk android:targetSdkVersion="23"/>
-
- <application
- android:theme="@style/Theme.Robolectric"/>
+ <uses-sdk android:targetSdkVersion="23"/>
+ <application
+ android:theme="@style/Theme.Robolectric">
+ <activity android:name=".DisabledTestActivity" android:enabled="false"/>
+ <activity android:name=".TestActivity"/>
+ </application>
</manifest>
diff --git a/testapp/src/main/java/org/robolectric/DisabledTestActivity.java b/testapp/src/main/java/org/robolectric/DisabledTestActivity.java
new file mode 100644
index 000000000..8b7b81a24
--- /dev/null
+++ b/testapp/src/main/java/org/robolectric/DisabledTestActivity.java
@@ -0,0 +1,6 @@
+package org.robolectric;
+
+import android.app.Activity;
+
+/** Test activity that is disabled in the manifest. */
+public class DisabledTestActivity extends Activity {}
diff --git a/testapp/src/main/java/org/robolectric/TestActivity.java b/testapp/src/main/java/org/robolectric/TestActivity.java
new file mode 100644
index 000000000..b53f24585
--- /dev/null
+++ b/testapp/src/main/java/org/robolectric/TestActivity.java
@@ -0,0 +1,6 @@
+package org.robolectric;
+
+import android.app.Activity;
+
+/** Test activity that is enabled in the manifest. */
+public class TestActivity extends Activity {}
diff --git a/testapp/src/main/res/font/vt323_regular.ttf b/testapp/src/main/res/font/vt323_regular.ttf
new file mode 100644
index 000000000..afa69098f
--- /dev/null
+++ b/testapp/src/main/res/font/vt323_regular.ttf
Binary files differ
diff --git a/testapp/src/main/res/values/ids.xml b/testapp/src/main/res/values/ids.xml
index 5e485d50b..3975c1c46 100644
--- a/testapp/src/main/res/values/ids.xml
+++ b/testapp/src/main/res/values/ids.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="id_declared_in_item_tag" type="id"/>
- <item name="id_with_string_value" type="id">string value</item>
-</resources> \ No newline at end of file
+ <item name="id_with_string_value" type="id"/>
+</resources>
diff --git a/testapp/src/main/res/values/plurals.xml b/testapp/src/main/res/values/plurals.xml
index c0ef236b6..823968a14 100644
--- a/testapp/src/main/res/values/plurals.xml
+++ b/testapp/src/main/res/values/plurals.xml
@@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="beer">
- <item quantity="zero">@string/howdy</item>
- <item quantity="one">One beer</item>
- <item quantity="two">Two beers</item>
- <item quantity="other">%d beers, yay!</item>
+ <!--
+ In us-en locale, only one and other plurals are used because there are only two possible
+ variants: singular vs plural tense.
+ -->
+ <item quantity="one">a beer</item>
+ <item quantity="other">some beers</item>
</plurals>
<plurals name="minute">
<item quantity="one">@string/minute_singular</item>
diff --git a/utils/build.gradle b/utils/build.gradle
index 3a3440f79..3c6ed75c5 100644
--- a/utils/build.gradle
+++ b/utils/build.gradle
@@ -1,17 +1,11 @@
-plugins {
- id "net.ltgt.errorprone" version "0.0.13"
-}
-
new RoboJavaModulePlugin(
deploy: true
).apply(project)
dependencies {
- // Compile dependencies
- compile project(":annotations")
+ api project(":annotations")
- // Testing dependencies
- testCompile "junit:junit:4.12"
- testCompile "com.google.truth:truth:0.39"
- testCompile "org.mockito:mockito-core:2.5.4"
-} \ No newline at end of file
+ testImplementation "junit:junit:4.12"
+ testImplementation "com.google.truth:truth:0.42"
+ testImplementation "org.mockito:mockito-core:2.5.4"
+}
diff --git a/utils/src/main/java/org/robolectric/util/Scheduler.java b/utils/src/main/java/org/robolectric/util/Scheduler.java
index d027af673..3813a4358 100644
--- a/utils/src/main/java/org/robolectric/util/Scheduler.java
+++ b/utils/src/main/java/org/robolectric/util/Scheduler.java
@@ -4,27 +4,27 @@ import static org.robolectric.util.Scheduler.IdleState.CONSTANT_IDLE;
import static org.robolectric.util.Scheduler.IdleState.PAUSED;
import static org.robolectric.util.Scheduler.IdleState.UNPAUSED;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.ListIterator;
+import java.util.Iterator;
+import java.util.PriorityQueue;
import java.util.concurrent.TimeUnit;
/**
- * Class that manages a queue of Runnables that are scheduled to run now (or at some time in
- * the future). Runnables that are scheduled to run on the UI thread (tasks, animations, etc)
- * eventually get routed to a Scheduler instance.
- *
- * The execution of a scheduler can be in one of three states:
- * <ul><li>paused ({@link #pause()}): if paused, then no posted events will be run unless the Scheduler
- * is explicitly instructed to do so.</li>
- * <li>normal ({@link #unPause()}): if not paused but not set to idle constantly, then the Scheduler will
- * automatically run any {@link Runnable}s that are scheduled to run at or before the
- * Scheduler's current time, but it won't automatically run any future events. To
- * run future events the Scheduler needs to have its clock advanced.</li>
- * <li>idling constantly: if {@link #idleConstantly(boolean)} is called with
- * <tt>true</tt>, then the Scheduler will continue looping through posted events
- * (including future events), advancing its clock as it goes.</li>
+ * Class that manages a queue of Runnables that are scheduled to run now (or at some time in the
+ * future). Runnables that are scheduled to run on the UI thread (tasks, animations, etc) eventually
+ * get routed to a Scheduler instance.
+ *
+ * <p>The execution of a scheduler can be in one of three states:
+ *
+ * <ul>
+ * <li>paused ({@link #pause()}): if paused, then no posted events will be run unless the
+ * Scheduler is explicitly instructed to do so, correctly matching Android's behavior.
+ * <li>normal ({@link #unPause()}): if not paused but not set to idle constantly, then the
+ * Scheduler will automatically run any {@link Runnable}s that are scheduled to run at or
+ * before the Scheduler's current time, but it won't automatically run any future events. To
+ * run future events the Scheduler needs to have its clock advanced.
+ * <li>idling constantly: if {@link #idleConstantly(boolean)} is called with <tt>true</tt>, then
+ * the Scheduler will continue looping through posted events (including future events),
+ * advancing its clock as it goes.
* </ul>
*/
public class Scheduler {
@@ -49,11 +49,17 @@ public class Scheduler {
CONSTANT_IDLE
}
- private final static long START_TIME = 100;
+ private static final long START_TIME = 100;
private volatile long currentTime = START_TIME;
+ /**
+ * PriorityQueue doesn't maintain ordering based on insertion; track that ourselves to preserve
+ * FIFO order for posted runnables with the same scheduled time.
+ */
+ private long nextTimeDisambiguator = 0;
+
private boolean isExecutingRunnable = false;
private final Thread associatedThread = Thread.currentThread();
- private final List<ScheduledRunnable> runnables = new ArrayList<>();
+ private final PriorityQueue<ScheduledRunnable> runnables = new PriorityQueue<>();
private volatile IdleState idleState = UNPAUSED;
/**
@@ -151,7 +157,7 @@ public class Scheduler {
public synchronized void postDelayed(Runnable runnable, long delay, TimeUnit unit) {
long delayMillis = unit.toMillis(delay);
if ((idleState != CONSTANT_IDLE && (isPaused() || delayMillis > 0)) || Thread.currentThread() != associatedThread) {
- queueRunnableAndSort(runnable, currentTime + delayMillis);
+ runnables.add(new ScheduledRunnable(runnable, currentTime + delayMillis));
} else {
runOrQueueRunnable(runnable, currentTime + delayMillis);
}
@@ -164,7 +170,13 @@ public class Scheduler {
*/
public synchronized void postAtFrontOfQueue(Runnable runnable) {
if (isPaused() || Thread.currentThread() != associatedThread) {
- runnables.add(0, new ScheduledRunnable(runnable, currentTime));
+ final long timeDisambiguator;
+ if (runnables.isEmpty()) {
+ timeDisambiguator = nextTimeDisambiguator++;
+ } else {
+ timeDisambiguator = runnables.peek().timeDisambiguator - 1;
+ }
+ runnables.add(new ScheduledRunnable(runnable, 0, timeDisambiguator));
} else {
runOrQueueRunnable(runnable, currentTime);
}
@@ -176,22 +188,28 @@ public class Scheduler {
* @param runnable Runnable to remove.
*/
public synchronized void remove(Runnable runnable) {
- ListIterator<ScheduledRunnable> iterator = runnables.listIterator();
+ Iterator<ScheduledRunnable> iterator = runnables.iterator();
while (iterator.hasNext()) {
- ScheduledRunnable next = iterator.next();
- if (next.runnable == runnable) {
+ if (iterator.next().runnable == runnable) {
iterator.remove();
}
}
}
/**
- * Run all runnables in the queue.
+ * Run all runnables in the queue, and any additional runnables they schedule that are scheduled
+ * before the latest scheduled runnable currently in the queue.
*
- * @return True if a runnable was executed.
+ * @return True if a runnable was executed.
*/
public synchronized boolean advanceToLastPostedRunnable() {
- return size() >= 1 && advanceTo(runnables.get(runnables.size() - 1).scheduledTime);
+ long currentMaxTime = currentTime;
+ for (ScheduledRunnable scheduled : runnables) {
+ if (currentMaxTime < scheduled.scheduledTime) {
+ currentMaxTime = scheduled.scheduledTime;
+ }
+ }
+ return advanceTo(currentMaxTime);
}
/**
@@ -200,7 +218,7 @@ public class Scheduler {
* @return True if a runnable was executed.
*/
public synchronized boolean advanceToNextPostedRunnable() {
- return size() >= 1 && advanceTo(runnables.get(0).scheduledTime);
+ return !runnables.isEmpty() && advanceTo(runnables.peek().scheduledTime);
}
/**
@@ -232,7 +250,7 @@ public class Scheduler {
* @return True if a runnable was executed.
*/
public synchronized boolean advanceTo(long endTime) {
- if (endTime - currentTime < 0 || size() < 1) {
+ if (endTime < currentTime || runnables.isEmpty()) {
currentTime = endTime;
return false;
}
@@ -252,14 +270,15 @@ public class Scheduler {
* @return True if a runnable was executed.
*/
public synchronized boolean runOneTask() {
- if (size() < 1) {
- return false;
+ ScheduledRunnable postedRunnable = runnables.poll();
+ if (postedRunnable != null) {
+ if (postedRunnable.scheduledTime > currentTime) {
+ currentTime = postedRunnable.scheduledTime;
+ }
+ postedRunnable.run();
+ return true;
}
-
- ScheduledRunnable postedRunnable = runnables.remove(0);
- currentTime = postedRunnable.scheduledTime;
- postedRunnable.run();
- return true;
+ return false;
}
/**
@@ -306,12 +325,12 @@ public class Scheduler {
}
private boolean nextTaskIsScheduledBefore(long endingTime) {
- return size() > 0 && runnables.get(0).scheduledTime <= endingTime;
+ return !runnables.isEmpty() && runnables.peek().scheduledTime <= endingTime;
}
private void runOrQueueRunnable(Runnable runnable, long scheduledTime) {
if (isExecutingRunnable) {
- queueRunnableAndSort(runnable, scheduledTime);
+ runnables.add(new ScheduledRunnable(runnable, scheduledTime));
return;
}
isExecutingRunnable = true;
@@ -337,23 +356,28 @@ public class Scheduler {
}
}
- private void queueRunnableAndSort(Runnable runnable, long scheduledTime) {
- runnables.add(new ScheduledRunnable(runnable, scheduledTime));
- Collections.sort(runnables);
- }
-
private class ScheduledRunnable implements Comparable<ScheduledRunnable> {
private final Runnable runnable;
private final long scheduledTime;
+ private final long timeDisambiguator;
private ScheduledRunnable(Runnable runnable, long scheduledTime) {
+ this(runnable, scheduledTime, nextTimeDisambiguator++);
+ }
+
+ private ScheduledRunnable(Runnable runnable, long scheduledTime, long timeDisambiguator) {
this.runnable = runnable;
this.scheduledTime = scheduledTime;
+ this.timeDisambiguator = timeDisambiguator;
}
@Override
public int compareTo(ScheduledRunnable runnable) {
- return Long.compare(scheduledTime, runnable.scheduledTime);
+ int timeCompare = Long.compare(scheduledTime, runnable.scheduledTime);
+ if (timeCompare == 0) {
+ return Long.compare(timeDisambiguator, runnable.timeDisambiguator);
+ }
+ return timeCompare;
}
public void run() {
diff --git a/utils/src/test/java/org/robolectric/util/SchedulerTest.java b/utils/src/test/java/org/robolectric/util/SchedulerTest.java
index 4fcfe1110..df3e583c2 100644
--- a/utils/src/test/java/org/robolectric/util/SchedulerTest.java
+++ b/utils/src/test/java/org/robolectric/util/SchedulerTest.java
@@ -5,8 +5,13 @@ import static org.robolectric.util.Scheduler.IdleState.CONSTANT_IDLE;
import static org.robolectric.util.Scheduler.IdleState.PAUSED;
import static org.robolectric.util.Scheduler.IdleState.UNPAUSED;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.Before;
import org.junit.Test;
@@ -456,6 +461,52 @@ public class SchedulerTest {
assertThat(runnablesThatWereRun).containsExactly(1, 2);
}
+ @Test
+ public void testTimeNotChangedByNegativeDelay() throws Exception {
+ long currentTime = scheduler.getCurrentTime();
+ long[] observedTime = new long[1];
+ scheduler.postDelayed(
+ new Runnable() {
+ @Override
+ public void run() {
+ observedTime[0] = scheduler.getCurrentTime();
+ }
+ },
+ -1000);
+ scheduler.advanceToLastPostedRunnable();
+ assertThat(observedTime[0]).isEqualTo(currentTime);
+ assertThat(scheduler.getCurrentTime()).isEqualTo(currentTime);
+ }
+
+ /** Tests for quadractic or exponential behavior in the scheduler, and stable sorting */
+ @Test(timeout = 1000)
+ public void schedulerWithManyRunnables() {
+ Random random = new Random(0);
+ Map<Integer, List<Integer>> orderCheck = new TreeMap<>();
+ List<Integer> actualOrder = new ArrayList<>();
+ for (int i = 0; i < 20_000; i++) {
+ int delay = random.nextInt(10);
+ List<Integer> list = orderCheck.get(delay);
+ if (list == null) {
+ list = new ArrayList<>();
+ orderCheck.put(delay, list);
+ }
+ list.add(i);
+ final int localI = i;
+ scheduler.postDelayed(
+ new Runnable() {
+ @Override
+ public void run() {
+ actualOrder.add(localI);
+ }
+ },
+ delay);
+ }
+ assertThat(actualOrder).isEmpty();
+ scheduler.advanceToLastPostedRunnable();
+ assertThat(actualOrder).isEqualTo(ImmutableList.copyOf(Iterables.concat(orderCheck.values())));
+ }
+
@Test(timeout=1000)
public void schedulerAllowsConcurrentTimeRead_whileLockIsHeld() throws InterruptedException {
final AtomicLong l = new AtomicLong();