aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRam Peri <ramperi@google.com>2023-05-18 23:14:37 -0400
committerRam Peri <ramperi@google.com>2023-05-19 13:10:46 -0400
commitd87c9a0b823e7b328d93d1024dd2b720cc12fb86 (patch)
treecd87342dab11bcc98795374ecdb61fc37ac60eda
parent6660b73edd97a19ea275f13329641cc28d474ce1 (diff)
downloadrobolectric-d87c9a0b823e7b328d93d1024dd2b720cc12fb86.tar.gz
merge upstream-google' into aosp
Test: atest MyRoboTests Bug: 281899632 Merged-In: I3f837c5db845de7dcf2cee799ed2af128d9e2eda Change-Id: I09a0b977ae9c39586c1cf7a871d7021d6297dca7
-rw-r--r--.github/workflows/gradle_tasks_validation.yml23
-rw-r--r--README.md17
-rw-r--r--annotations/build.gradle2
-rw-r--r--build.gradle19
-rw-r--r--buildSrc/build.gradle8
-rw-r--r--buildSrc/settings.gradle7
-rw-r--r--buildSrc/src/main/groovy/CheckApiChangesPlugin.groovy1
-rw-r--r--buildSrc/src/main/groovy/org/robolectric/gradle/RoboJavaModulePlugin.groovy4
-rw-r--r--dependencies.gradle47
-rw-r--r--errorprone/build.gradle22
-rw-r--r--gradle.properties2
-rw-r--r--gradle/libs.versions.toml237
-rw-r--r--integration_tests/agp/build.gradle9
-rw-r--r--integration_tests/agp/testsupport/build.gradle1
-rw-r--r--integration_tests/androidx/build.gradle23
-rw-r--r--integration_tests/androidx_test/build.gradle49
-rw-r--r--integration_tests/compat-target28/build.gradle7
-rw-r--r--integration_tests/compat-target28/src/test/java/org/robolectric/integration/compat/target28/NormalCompatibilityTest.kt7
-rw-r--r--integration_tests/ctesque/build.gradle39
-rw-r--r--integration_tests/dependency-on-stubs/build.gradle8
-rw-r--r--integration_tests/jacoco-offline/build.gradle4
-rw-r--r--integration_tests/kotlin/build.gradle6
-rw-r--r--integration_tests/kotlin/src/test/kotlin/org/robolectric/integrationtests/kotlin/ParameterizedRobolectricTestRunnerTest.kt28
-rw-r--r--integration_tests/libphonenumber/build.gradle8
-rw-r--r--integration_tests/memoryleaks/build.gradle7
-rw-r--r--integration_tests/mockito-experimental/build.gradle6
-rw-r--r--integration_tests/mockito-kotlin/build.gradle8
-rw-r--r--integration_tests/mockito/build.gradle8
-rw-r--r--integration_tests/mockk/build.gradle6
-rw-r--r--integration_tests/nativegraphics/build.gradle11
-rw-r--r--integration_tests/play_services/build.gradle6
-rw-r--r--integration_tests/powermock/build.gradle11
-rw-r--r--integration_tests/security-providers/build.gradle10
-rw-r--r--integration_tests/sparsearray/build.gradle7
-rw-r--r--junit/build.gradle4
-rw-r--r--nativeruntime/build.gradle12
-rw-r--r--nativeruntime/src/test/java/org/robolectric/nativeruntime/DefaultNativeRuntimeLoaderTest.java6
-rw-r--r--pluginapi/build.gradle10
-rw-r--r--plugins/maven-dependency-resolver/build.gradle19
-rw-r--r--plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenArtifactFetcher.java51
-rw-r--r--[-rwxr-xr-x]plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenDependencyResolver.java0
-rw-r--r--preinstrumented/build.gradle10
-rw-r--r--processor/build.gradle22
-rw-r--r--resources/build.gradle12
-rw-r--r--resources/src/main/java/org/robolectric/manifest/AndroidManifest.java8
-rw-r--r--robolectric/build.gradle31
-rw-r--r--robolectric/src/main/java/org/robolectric/android/internal/AndroidTestEnvironment.java36
-rw-r--r--[-rwxr-xr-x]robolectric/src/main/java/org/robolectric/internal/AndroidSandbox.java0
-rw-r--r--[-rwxr-xr-x]robolectric/src/main/java/org/robolectric/internal/dependency/PropertiesDependencyResolver.java0
-rw-r--r--robolectric/src/test/java/org/robolectric/CustomAppComponentFactory.java22
-rw-r--r--robolectric/src/test/java/org/robolectric/CustomConstructorReceiverWrapper.java32
-rw-r--r--robolectric/src/test/java/org/robolectric/android/DrawableResourceLoaderTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/android/ResourceLoaderTest.java15
-rw-r--r--robolectric/src/test/java/org/robolectric/android/ResourceTableFactoryIntegrationTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/android/XmlResourceParserImplTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/android/internal/AndroidTestEnvironmentCreateApplicationTest.java2
-rw-r--r--robolectric/src/test/java/org/robolectric/android/internal/AndroidTestEnvironmentTest.java4
-rw-r--r--robolectric/src/test/java/org/robolectric/interceptors/AndroidInterceptorsIntegrationTest.java2
-rw-r--r--[-rwxr-xr-x]robolectric/src/test/java/org/robolectric/internal/MavenManifestFactoryTest.java0
-rw-r--r--[-rwxr-xr-x]robolectric/src/test/java/org/robolectric/internal/dependency/PropertiesDependencyResolverTest.java0
-rw-r--r--robolectric/src/test/java/org/robolectric/res/StyleResourceLoaderTest.java8
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/CellIdentityNrBuilderTest.java90
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/CellInfoNrBuilderTest.java76
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/CellSignalStrengthNrBuilderTest.java84
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowAssetManagerTest.java21
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowContextWrapperTest.java17
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowLauncherAppsTest.java14
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPaintTest.java9
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowPausedLooperTest.java39
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowResourcesTest.java7
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowSQLiteConnectionTest.java24
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyManagerTest.java36
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowVibratorTest.java43
-rw-r--r--robolectric/src/test/java/org/robolectric/util/SQLiteLibraryLoaderTest.java4
-rw-r--r--robolectric/src/test/resources/TestAndroidManifestWithAppComponentFactory.xml16
-rw-r--r--sandbox/build.gradle24
-rw-r--r--shadowapi/build.gradle10
-rw-r--r--shadowapi/src/main/java/org/robolectric/util/ReflectionHelpers.java56
-rw-r--r--shadowapi/src/test/java/org/robolectric/util/ReflectionHelpersTest.java38
-rw-r--r--shadows/framework/build.gradle25
-rw-r--r--[-rwxr-xr-x]shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java0
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/AssociationInfoBuilder.java47
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/CellIdentityNrBuilder.java135
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/CellInfoLteBuilder.java8
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/CellInfoNrBuilder.java93
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/CellSignalStrengthNrBuilder.java140
-rw-r--r--[-rwxr-xr-x]shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscApkAssets9.java0
-rw-r--r--[-rwxr-xr-x]shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager.java0
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayManagerGlobal.java27
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowLauncherApps.java17
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowLoadedApk.java53
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeFontsFontFamily.java11
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java9
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPausedMessageQueue.java41
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemVibrator.java18
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephonyManager.java25
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowVibrator.java15
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebView.java2
-rw-r--r--shadows/httpclient/build.gradle14
-rw-r--r--shadows/playservices/build.gradle19
-rw-r--r--testapp/build.gradle1
-rw-r--r--utils/build.gradle28
-rw-r--r--utils/reflector/build.gradle10
-rw-r--r--[-rwxr-xr-x]utils/src/main/java/org/robolectric/util/Util.java0
104 files changed, 1806 insertions, 516 deletions
diff --git a/.github/workflows/gradle_tasks_validation.yml b/.github/workflows/gradle_tasks_validation.yml
index 96b4b3307..9762b9e51 100644
--- a/.github/workflows/gradle_tasks_validation.yml
+++ b/.github/workflows/gradle_tasks_validation.yml
@@ -15,6 +15,23 @@ permissions:
contents: read
jobs:
+ run_checkForApiChanges:
+ runs-on: ubuntu-20.04
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Set up JDK
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'zulu'
+ java-version: 11
+
+ - uses: gradle/gradle-build-action@v2
+
+ - name: Run checkForApiChanges
+ run: ./gradlew checkForApiChanges
+
run_aggregateDocs:
runs-on: ubuntu-20.04
@@ -30,7 +47,7 @@ jobs:
- uses: gradle/gradle-build-action@v2
- name: Run aggregateDocs
- run: SKIP_NATIVERUNTIME_BUILD=true ./gradlew clean aggregateDocs # building the native runtime is not required for checking javadoc
+ run: ./gradlew clean aggregateDocs
run_instrumentAll:
runs-on: ubuntu-20.04
@@ -50,7 +67,7 @@ jobs:
- uses: gradle/gradle-build-action@v2
- name: Run :preinstrumented:instrumentAll
- run: SKIP_NATIVERUNTIME_BUILD=true ./gradlew :preinstrumented:instrumentAll
+ run: ./gradlew :preinstrumented:instrumentAll
- name: Run :preinstrumented:instrumentAll with SDK 33
- run: SKIP_NATIVERUNTIME_BUILD=true PREINSTRUMENTED_SDK_VERSIONS=33 ./gradlew :preinstrumented:instrumentAll
+ run: PREINSTRUMENTED_SDK_VERSIONS=33 ./gradlew :preinstrumented:instrumentAll
diff --git a/README.md b/README.md
index 6b91ba31d..b183647e0 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ If you'd like to start a new project with Robolectric tests you can refer to `de
```groovy
testImplementation "junit:junit:4.13.2"
-testImplementation "org.robolectric:robolectric:4.10-alpha-1"
+testImplementation "org.robolectric:robolectric:4.10.3"
```
## Building And Contributing
@@ -79,18 +79,3 @@ Run compatibility test suites on opening Emulator:
./gradlew connectedCheck
-### Using Snapshots
-
-If you would like to live on the bleeding edge, you can try running against a snapshot build. Keep in mind that snapshots represent the most recent changes on master and may contain bugs.
-
-#### build.gradle:
-
-```groovy
-repositories {
- maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
-}
-
-dependencies {
- testImplementation "org.robolectric:robolectric:4.10-SNAPSHOT"
-}
-```
diff --git a/annotations/build.gradle b/annotations/build.gradle
index 65b4f06bb..d8bd113c5 100644
--- a/annotations/build.gradle
+++ b/annotations/build.gradle
@@ -5,6 +5,6 @@ apply plugin: RoboJavaModulePlugin
apply plugin: DeployedRoboJavaModulePlugin
dependencies {
- compileOnly "com.google.code.findbugs:jsr305:3.0.2"
+ compileOnly libs.findbugs.jsr305
compileOnly AndroidSdk.MAX_SDK.coordinates
}
diff --git a/build.gradle b/build.gradle
index 1eb662b1f..f3ab387aa 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,18 +7,15 @@ buildscript {
google()
mavenCentral()
gradlePluginPortal()
- maven {
- url "https://plugins.gradle.org/m2/"
- }
}
dependencies {
gradle
- classpath 'com.android.tools.build:gradle:7.4.2'
- classpath 'net.ltgt.gradle:gradle-errorprone-plugin:3.0.1'
- classpath 'com.netflix.nebula:gradle-aggregate-javadocs-plugin:3.0.1'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
- classpath "com.diffplug.spotless:spotless-plugin-gradle:6.17.0"
+ classpath libs.android.gradle
+ classpath libs.error.prone.gradle
+ classpath libs.aggregate.javadocs.gradle
+ classpath libs.kotlin.gradle
+ classpath libs.spotless.gradle
}
}
@@ -120,7 +117,7 @@ task aggregateDocs {
dependsOn ':aggregateJsondocs'
}
-task prefetchSdks() {
+tasks.register('prefetchSdks') {
AndroidSdk.ALL_SDKS.each { androidSdk ->
doLast {
println("Prefetching ${androidSdk.coordinates}...")
@@ -139,7 +136,7 @@ task prefetchSdks() {
}
}
-task prefetchInstrumentedSdks() {
+tasks.register('prefetchInstrumentedSdks') {
AndroidSdk.ALL_SDKS.each { androidSdk ->
doLast {
println("Prefetching ${androidSdk.preinstrumentedCoordinates}...")
@@ -169,7 +166,7 @@ private void shellExec(String mvnCommand) {
if (process.exitValue() != 0) System.exit(1)
}
-task prefetchDependencies() {
+tasks.register('prefetchDependencies') {
doLast {
allprojects.each { p ->
p.configurations.each { config ->
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index 612366308..67279efee 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -11,8 +11,8 @@ dependencies {
implementation gradleApi()
implementation localGroovy()
- api "com.google.guava:guava:31.1-jre"
- api 'org.jetbrains:annotations:24.0.1'
- implementation "org.ow2.asm:asm-tree:9.4"
- implementation 'com.android.tools.build:gradle:7.4.2'
+ api libs.guava
+ api libs.jetbrains.annotations
+ implementation libs.asm.tree
+ implementation libs.android.gradle
}
diff --git a/buildSrc/settings.gradle b/buildSrc/settings.gradle
new file mode 100644
index 000000000..6f31e6ef7
--- /dev/null
+++ b/buildSrc/settings.gradle
@@ -0,0 +1,7 @@
+dependencyResolutionManagement {
+ versionCatalogs {
+ libs {
+ from(files("../gradle/libs.versions.toml"))
+ }
+ }
+}
diff --git a/buildSrc/src/main/groovy/CheckApiChangesPlugin.groovy b/buildSrc/src/main/groovy/CheckApiChangesPlugin.groovy
index c0671c598..2f1476cf3 100644
--- a/buildSrc/src/main/groovy/CheckApiChangesPlugin.groovy
+++ b/buildSrc/src/main/groovy/CheckApiChangesPlugin.groovy
@@ -28,7 +28,6 @@ class CheckApiChangesPlugin implements Plugin<Project> {
project.checkApiChanges.from.each {
project.dependencies.checkApiChangesFrom(it) {
transitive = false
- force = true
}
}
diff --git a/buildSrc/src/main/groovy/org/robolectric/gradle/RoboJavaModulePlugin.groovy b/buildSrc/src/main/groovy/org/robolectric/gradle/RoboJavaModulePlugin.groovy
index 6c0e05894..deb97c994 100644
--- a/buildSrc/src/main/groovy/org/robolectric/gradle/RoboJavaModulePlugin.groovy
+++ b/buildSrc/src/main/groovy/org/robolectric/gradle/RoboJavaModulePlugin.groovy
@@ -13,8 +13,8 @@ class RoboJavaModulePlugin implements Plugin<Project> {
if (!skipErrorprone) {
apply plugin: "net.ltgt.errorprone"
project.dependencies {
- errorprone("com.google.errorprone:error_prone_core:$errorproneVersion")
- errorproneJavac("com.google.errorprone:javac:$errorproneJavacVersion")
+ errorprone(libs.error.prone.core)
+ errorproneJavac(libs.error.prone.javac)
}
}
diff --git a/dependencies.gradle b/dependencies.gradle
index b890dc16d..204e3d354 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -1,40 +1,11 @@
ext {
- apiCompatVersion='4.9.2'
-
- errorproneVersion='2.18.0'
- errorproneJavacVersion='9+181-r4173-1'
-
- // AndroidX test versions
- axtMonitorVersion='1.6.1'
- axtRunnerVersion='1.5.2'
- axtRulesVersion='1.5.0'
- axtCoreVersion='1.5.0'
- axtTruthVersion='1.5.0'
- espressoVersion='3.5.1'
- axtJunitVersion='1.1.4'
- axtTestServicesVersion='1.4.2'
-
- // AndroidX versions
- coreVersion='1.9.0'
- appCompatVersion='1.6.1'
- constraintlayoutVersion='2.1.4'
- windowVersion='1.0.0'
- fragmentVersion='1.5.5'
-
- truthVersion='1.1.3'
-
- junitVersion='4.13.2'
-
- mockitoVersion='4.11.0'
-
- jacocoVersion='0.8.8'
-
- guavaJREVersion='31.1-jre'
-
- asmVersion='9.4'
-
- kotlinVersion='1.8.10'
- autoServiceVersion='1.0.1'
- multidexVersion='2.0.1'
- sqlite4javaVersion='1.0.392'
+ apiCompatVersion = libs.versions.robolectric.compat.get()
+
+ // https://github.com/gradle/gradle/issues/21267
+ axtCoreVersion = libs.versions.androidx.test.core.get()
+ axtJunitVersion = libs.versions.androidx.test.ext.junit.get()
+ axtMonitorVersion = libs.versions.androidx.test.monitor.get()
+ axtRunnerVersion = libs.versions.androidx.test.runner.get()
+ axtTruthVersion = libs.versions.androidx.test.ext.truth.get()
+ espressoVersion = libs.versions.androidx.test.espresso.get()
}
diff --git a/errorprone/build.gradle b/errorprone/build.gradle
index 1932066ae..5fc561605 100644
--- a/errorprone/build.gradle
+++ b/errorprone/build.gradle
@@ -20,14 +20,14 @@ dependencies {
implementation project(":shadowapi")
// Compile dependencies
- implementation "com.google.errorprone:error_prone_annotation:$errorproneVersion"
- implementation "com.google.errorprone:error_prone_refaster:$errorproneVersion"
- implementation "com.google.errorprone:error_prone_check_api:$errorproneVersion"
- compileOnly "com.google.auto.service:auto-service-annotations:$autoServiceVersion"
- compileOnly(AndroidSdk.MAX_SDK.coordinates) { force = true }
+ implementation libs.error.prone.annotations
+ implementation libs.error.prone.refaster
+ implementation libs.error.prone.check.api
+ compileOnly libs.auto.service.annotations
+ compileOnly(AndroidSdk.MAX_SDK.coordinates)
- annotationProcessor "com.google.auto.service:auto-service:$autoServiceVersion"
- annotationProcessor "com.google.errorprone:error_prone_core:$errorproneVersion"
+ annotationProcessor libs.auto.service
+ annotationProcessor libs.error.prone.core
// in jdk 9, tools.jar disappears!
def toolsJar = Jvm.current().getToolsJar()
@@ -36,10 +36,10 @@ dependencies {
}
// Testing dependencies
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation("com.google.errorprone:error_prone_test_helpers:${errorproneVersion}") {
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation(libs.error.prone.test.helpers) {
exclude group: 'junit', module: 'junit' // because it depends on a snapshot!?
}
- testCompileOnly(AndroidSdk.MAX_SDK.coordinates) { force = true }
+ testCompileOnly(AndroidSdk.MAX_SDK.coordinates)
}
diff --git a/gradle.properties b/gradle.properties
index dc9eb66c0..d97ed211a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,3 +1,3 @@
-thisVersion=4.10-SNAPSHOT
+thisVersion=4.11-SNAPSHOT
android.useAndroidX=true
kotlin.stdlib.default.dependency=false
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
new file mode 100644
index 000000000..7b43dfa1f
--- /dev/null
+++ b/gradle/libs.versions.toml
@@ -0,0 +1,237 @@
+[versions]
+robolectric-compat = "4.10.2"
+robolectric-nativeruntime-dist-compat = "1.0.1"
+
+# https://developer.android.com/studio/releases
+android-gradle = "7.4.2"
+
+# https://github.com/google/conscrypt/tags
+conscrypt = "2.5.2"
+
+# https://github.com/bcgit/bc-java/tags
+bouncycastle = "1.73"
+
+# https://github.com/findbugsproject/findbugs/tags
+findbugs-jsr305 = "3.0.2"
+
+# https://github.com/hamcrest/JavaHamcrest/releases
+hamcrest = "2.0.0.0"
+
+# https://github.com/nebula-plugins/gradle-aggregate-javadocs-plugin/releases
+aggregate-javadocs-gradle = "3.0.1"
+
+# https://github.com/google/error-prone/releases
+error-prone = "2.19.1"
+error-prone-javac = "9+181-r4173-1"
+
+# https://github.com/tbroyer/gradle-errorprone-plugin/releases
+error-prone-gradle = "3.1.0"
+
+# https://kotlinlang.org/docs/releases.html#release-details
+kotlin = "1.8.10"
+
+# https://github.com/diffplug/spotless/blob/main/CHANGES.md
+spotless-gradle = "6.18.0"
+
+# https://hc.apache.org/news.html
+apache-http-core = "4.0.1"
+apache-http-client = "4.0.3"
+
+# https://asm.ow2.io/versions.html
+asm = "9.5"
+
+# https://github.com/google/auto/releases
+auto-common = "1.2.1"
+auto-service = "1.0.1"
+auto-value = "1.10.1"
+
+compile-testing = "0.21.0"
+
+# https://github.com/google/guava/releases
+guava-jre = "31.1-jre"
+
+# https://github.com/google/gson/releases
+gson = "2.10.1"
+
+# https://github.com/google/truth/releases
+truth = "1.1.3"
+
+# https://github.com/unicode-org/icu/releases
+icu4j = "73.1"
+
+jacoco = "0.8.10"
+
+# https://github.com/javaee/javax.annotation/tags
+javax-annotation-api = "1.3.2"
+javax-annotation-jsr250-api = "1.0"
+javax-inject = "1"
+
+# https://github.com/JetBrains/java-annotations/releases
+jetbrains-annotations = "24.0.1"
+
+# https://junit.org/junit4/
+junit4 = "4.13.2"
+
+# https://github.com/google/libphonenumber/releases
+libphonenumber = "8.13.11"
+
+# https://github.com/mockito/mockito/releases
+mockito = "4.11.0"
+
+# https://github.com/mockk/mockk/releases
+mockk = "1.13.5"
+
+# https://square.github.io/okhttp/changelogs/changelog/
+okhttp = "4.11.0"
+
+# https://github.com/powermock/powermock/releases
+powermock = "2.0.9"
+
+sqlite4java = "1.0.392"
+
+# https://developer.android.com/jetpack/androidx/versions
+androidx-annotation = "1.3.0"
+androidx-appcompat = "1.6.1"
+androidx-constraintlayout = "2.1.4"
+androidx-core = "1.10.1"
+androidx-fragment = "1.5.7"
+androidx-multidex = "2.0.1"
+androidx-window = "1.0.0"
+
+# https://github.com/android/android-test/tags
+androidx-test-annotation = "1.0.1"
+androidx-test-core = "1.5.0"
+androidx-test-espresso = "3.5.1"
+androidx-test-ext-junit = "1.1.5"
+androidx-test-ext-truth = "1.5.0"
+androidx-test-monitor="1.6.1"
+androidx-test-orchestrator="1.4.2"
+androidx-test-runner = "1.5.2"
+androidx-test-services = "1.4.2"
+
+# for shadows/playservices/build.gradle
+androidx-fragment-for-shadows = "1.2.0"
+play-services-base-for-shadows = "8.4.0"
+
+[libraries]
+android-gradle = { module = "com.android.tools.build:gradle", version.ref = "android-gradle" }
+kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
+spotless-gradle = { module = "com.diffplug.spotless:spotless-plugin-gradle", version.ref = "spotless-gradle" }
+
+kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
+
+auto-common = { module = "com.google.auto:auto-common", version.ref = "auto-common" }
+auto-service-annotations = { module = "com.google.auto.service:auto-service-annotations", version.ref = "auto-service" }
+auto-service = { module = "com.google.auto.service:auto-service", version.ref = "auto-service" }
+auto-value-annotations = { module = "com.google.auto.value:auto-value-annotations", version.ref = "auto-value" }
+auto-value = { module = "com.google.auto.value:auto-value", version.ref = "auto-value" }
+
+apache-http-core = { module = "org.apache.httpcomponents:httpcore", version.ref = "apache-http-core" }
+apache-http-client = { module = "org.apache.httpcomponents:httpclient", version.ref = "apache-http-client" }
+
+asm = { module = "org.ow2.asm:asm", version.ref = "asm" }
+asm-commons = { module = "org.ow2.asm:asm-commons", version.ref = "asm" }
+asm-util = { module = "org.ow2.asm:asm-util", version.ref = "asm" }
+asm-tree = { module = "org.ow2.asm:asm-tree", version.ref = "asm" }
+
+compile-testing = { module = "com.google.testing.compile:compile-testing", version.ref = "compile-testing" }
+
+aggregate-javadocs-gradle = { module = "com.netflix.nebula:gradle-aggregate-javadocs-plugin", version.ref = "aggregate-javadocs-gradle" }
+
+error-prone-core = { module = "com.google.errorprone:error_prone_core", version.ref = "error-prone" }
+error-prone-annotations = { module = "com.google.errorprone:error_prone_annotation", version.ref = "error-prone" }
+error-prone-refaster= { module = "com.google.errorprone:error_prone_refaster", version.ref = "error-prone" }
+error-prone-check-api = { module = "com.google.errorprone:error_prone_check_api", version.ref = "error-prone" }
+error-prone-test-helpers = { module = "com.google.errorprone:error_prone_test_helpers", version.ref = "error-prone" }
+error-prone-javac = { module = "com.google.errorprone:javac", version.ref = "error-prone-javac" }
+
+error-prone-gradle = { module = "net.ltgt.gradle:gradle-errorprone-plugin", version.ref = "error-prone-gradle" }
+
+conscrypt-openjdk-uber = { module = "org.conscrypt:conscrypt-openjdk-uber", version.ref = "conscrypt" }
+bcprov-jdk18on = { module = "org.bouncycastle:bcprov-jdk18on", version.ref = "bouncycastle" }
+findbugs-jsr305 = { module = "com.google.code.findbugs:jsr305", version.ref = "findbugs-jsr305" }
+
+guava = { module = "com.google.guava:guava", version.ref = "guava-jre" }
+guava-testlib = { module = "com.google.guava:guava-testlib", version.ref = "guava-jre" }
+gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
+hamcrest-junit = { module = "org.hamcrest:hamcrest-junit", version.ref = "hamcrest" }
+
+icu4j = { module = "com.ibm.icu:icu4j", version.ref = "icu4j" }
+
+jacoco-agent = { module = "org.jacoco:org.jacoco.agent", version.ref = "jacoco" }
+junit4 = { module = "junit:junit", version.ref = "junit4" }
+
+javax-annotation-api = { module = "javax.annotation:javax.annotation-api", version.ref = "javax-annotation-api" }
+javax-annotation-jsr250-api = { module = "javax.annotation:jsr250-api", version.ref = "javax-annotation-jsr250-api" }
+javax-inject = { module = "javax.inject:javax.inject", version.ref = "javax.inject" }
+
+jetbrains-annotations = { module = "org.jetbrains:annotations", version.ref = "jetbrains-annotations" }
+
+libphonenumber = { module = "com.googlecode.libphonenumber:libphonenumber", version.ref = "libphonenumber" }
+
+okhttp = { module = "com.squareup.okhttp3:okhttp" }
+okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "okhttp" }
+
+powermock-module-junit4 = { module = "org.powermock:powermock-module-junit4", version.ref = "powermock" }
+powermock-module-junit4-rule = { module = "org.powermock:powermock-module-junit4-rule", version.ref = "powermock" }
+powermock-api-mockito2 = { module = "org.powermock:powermock-api-mockito2", version.ref = "powermock" }
+powermock-classloading-xstream = { module = "org.powermock:powermock-classloading-xstream", version.ref = "powermock" }
+
+robolectric-nativeruntime-dist-compat = { module = "org.robolectric:nativeruntime-dist-compat", version.ref = "robolectric-nativeruntime-dist-compat" }
+
+sqlite4java = { module = "com.almworks.sqlite4java:sqlite4java", version.ref = "sqlite4java" }
+sqlite4java-osx = { module = "com.almworks.sqlite4java:libsqlite4java-osx", version.ref = "sqlite4java" }
+sqlite4java-linux-amd64 = { module = "com.almworks.sqlite4java:libsqlite4java-linux-amd64", version.ref = "sqlite4java" }
+sqlite4java-win32-x64 = { module = "com.almworks.sqlite4java:sqlite4java-win32-x64", version.ref = "sqlite4java" }
+sqlite4java-linux-i386 = { module = "com.almworks.sqlite4java:libsqlite4java-linux-i386", version.ref = "sqlite4java" }
+sqlite4java-win32-x86 = { module = "com.almworks.sqlite4java:sqlite4java-win32-x86", version.ref = "sqlite4java" }
+
+truth = { module = "com.google.truth:truth", version.ref = "truth" }
+truth-java8-extension = { module = "com.google.truth.extensions:truth-java8-extension", version.ref = "truth" }
+
+mockito = { module = "org.mockito:mockito-core", version.ref = "mockito" }
+mockito-inline = { module = "org.mockito:mockito-inline", version.ref = "mockito" }
+mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
+
+androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidx-annotation" }
+androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
+androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidx-constraintlayout" }
+androidx-core = { module = "androidx.core:core", version.ref = "androidx-core" }
+androidx-fragment = { module = "androidx.fragment:fragment", version.ref = "androidx-fragment" }
+androidx-fragment-testing = { module = "androidx.fragment:fragment-testing", version.ref = "androidx-fragment" }
+androidx-multidex = { module = "androidx.multidex:multidex", version.ref = "androidx-multidex" }
+androidx-window = { module = "androidx.window:window", version.ref = "androidx-window" }
+
+androidx-test-annotation = { module = "androidx.test:annotation", version.ref = "androidx-test-annotation" }
+androidx-test-core = { module = "androidx.test:core", version.ref = "androidx-test-core" }
+androidx-test-monitor = { module = "androidx.test:monitor", version.ref = "androidx-test-monitor" }
+androidx-test-orchestrator = { module = "androidx.test:orchestrator", version.ref = "androidx-test-orchestrator" }
+androidx-test-rules = { module = "androidx.test:rules", version.ref = "androidx-test-core" }
+androidx-test-runner = { module = "androidx.test:runner", version.ref = "androidx-test-runner" }
+androidx-test-services = { module = "androidx.test.services:test-services", version.ref = "androidx-test-services" }
+androidx-test-services-storage = { module = "androidx.test.services:storage", version.ref = "androidx-test-services" }
+
+androidx-test-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-test-espresso" }
+androidx-test-espresso-accessibility = { module = "androidx.test.espresso:espresso-accessibility", version.ref = "androidx-test-espresso" }
+androidx-test-espresso-contrib = { module = "androidx.test.espresso:espresso-contrib", version.ref = "androidx-test-espresso" }
+androidx-test-espresso-intents = { module = "androidx.test.espresso:espresso-intents", version.ref = "androidx-test-espresso" }
+androidx-test-espresso-remote = { module = "androidx.test.espresso:espresso-remote", version.ref = "androidx-test-espresso" }
+androidx-test-espresso-web = { module = "androidx.test.espresso:espresso-web", version.ref = "androidx-test-espresso" }
+
+androidx-test-espresso-idling-resource = { module = "androidx.test.espresso:espresso-idling-resource", version.ref = "androidx-test-espresso" }
+androidx-test-espresso-idling-concurrent = { module = "androidx.test.espresso.idling:idling-concurrent", version.ref = "androidx-test-espresso" }
+androidx-test-espresso-idling-net = { module = "androidx.test.espresso.idling:idling-net", version.ref = "androidx-test-espresso" }
+
+androidx-test-ext-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-test-ext-junit" }
+androidx-test-ext-truth = { module = "androidx.test.ext:truth", version.ref = "androidx-test-ext-truth" }
+
+androidx-fragment-for-shadows = { module = "androidx.fragment:fragment", version.ref = "androidx-fragment-for-shadows" }
+play-services-base-for-shadows = { module = "com.google.android.gms:play-services-base", version.ref = "play-services-base-for-shadows" }
+play-services-basement-for-shadows = { module = "com.google.android.gms:play-services-basement", version.ref = "play-services-base-for-shadows" }
+
+[bundles]
+play-services-base-for-shadows = [ "androidx-fragment-for-shadows", "play-services-base-for-shadows", "play-services-basement-for-shadows" ]
+powermock = [ "powermock-module-junit4", "powermock-module-junit4-rule", "powermock-api-mockito2", "powermock-classloading-xstream" ]
+sqlite4java-native = [ "sqlite4java-osx", "sqlite4java-linux-amd64", "sqlite4java-win32-x64", "sqlite4java-linux-i386", "sqlite4java-win32-x86" ]
+
+[plugins]
diff --git a/integration_tests/agp/build.gradle b/integration_tests/agp/build.gradle
index a079d1ecf..55d90516f 100644
--- a/integration_tests/agp/build.gradle
+++ b/integration_tests/agp/build.gradle
@@ -5,6 +5,7 @@ apply plugin: AndroidProjectConfigPlugin
android {
compileSdk 33
+ namespace 'org.robolectric.integrationtests.agp'
defaultConfig {
minSdk 16
@@ -25,8 +26,8 @@ dependencies {
testImplementation project(":robolectric")
testImplementation project(":integration_tests:agp:testsupport")
- testImplementation "junit:junit:${junitVersion}"
- testImplementation("androidx.test:core:$axtCoreVersion")
- testImplementation("androidx.test:runner:$axtRunnerVersion")
- testImplementation("androidx.test.ext:junit:$axtJunitVersion")
+ testImplementation libs.junit4
+ testImplementation libs.androidx.test.core
+ testImplementation libs.androidx.test.runner
+ testImplementation libs.androidx.test.ext.junit
}
diff --git a/integration_tests/agp/testsupport/build.gradle b/integration_tests/agp/testsupport/build.gradle
index dcec3d41d..e87274f2b 100644
--- a/integration_tests/agp/testsupport/build.gradle
+++ b/integration_tests/agp/testsupport/build.gradle
@@ -2,6 +2,7 @@ apply plugin: 'com.android.library'
android {
compileSdk 33
+ namespace 'org.robolectric.integrationtests.agp.testsupport'
defaultConfig {
minSdk 16
diff --git a/integration_tests/androidx/build.gradle b/integration_tests/androidx/build.gradle
index 96535e1dd..10cc8c650 100644
--- a/integration_tests/androidx/build.gradle
+++ b/integration_tests/androidx/build.gradle
@@ -5,6 +5,7 @@ apply plugin: AndroidProjectConfigPlugin
android {
compileSdk 33
+ namespace 'org.robolectric.integrationtests.androidx'
defaultConfig {
minSdk 16
@@ -25,19 +26,19 @@ android {
}
dependencies {
- implementation("androidx.appcompat:appcompat:$appCompatVersion")
- implementation("androidx.window:window:$windowVersion")
+ implementation libs.androidx.appcompat
+ implementation libs.androidx.window
// Testing dependencies
testImplementation project(path: ':testapp')
testImplementation project(":robolectric")
- testImplementation "junit:junit:$junitVersion"
- testImplementation("androidx.test:core:$axtCoreVersion")
- testImplementation("androidx.core:core:$coreVersion")
- testImplementation("androidx.test:runner:$axtRunnerVersion")
- testImplementation("androidx.test:rules:$axtRulesVersion")
- testImplementation("androidx.test.espresso:espresso-intents:$espressoVersion")
- testImplementation("androidx.test.ext:truth:$axtTruthVersion")
- testImplementation("androidx.test.ext:junit:$axtJunitVersion")
- testImplementation("com.google.truth:truth:$truthVersion")
+ testImplementation libs.junit4
+ testImplementation libs.androidx.test.core
+ testImplementation libs.androidx.core
+ testImplementation libs.androidx.test.runner
+ testImplementation libs.androidx.test.rules
+ testImplementation libs.androidx.test.espresso.intents
+ testImplementation libs.androidx.test.ext.truth
+ testImplementation libs.androidx.test.ext.junit
+ testImplementation libs.truth
}
diff --git a/integration_tests/androidx_test/build.gradle b/integration_tests/androidx_test/build.gradle
index 7f6f621b6..d07ef2ed6 100644
--- a/integration_tests/androidx_test/build.gradle
+++ b/integration_tests/androidx_test/build.gradle
@@ -7,6 +7,7 @@ apply plugin: GradleManagedDevicePlugin
android {
compileSdk 33
+ namespace 'org.robolectric.integration.axt'
defaultConfig {
minSdk 16
@@ -41,33 +42,33 @@ android {
}
dependencies {
- implementation "androidx.appcompat:appcompat:$appCompatVersion"
- implementation "androidx.constraintlayout:constraintlayout:$constraintlayoutVersion"
- implementation "androidx.multidex:multidex:$multidexVersion"
+ implementation libs.androidx.appcompat
+ implementation libs.androidx.constraintlayout
+ implementation libs.androidx.multidex
// Testing dependencies
testImplementation project(":robolectric")
- testImplementation "androidx.test:runner:$axtRunnerVersion"
- testImplementation "junit:junit:$junitVersion"
- testImplementation "androidx.test:rules:$axtRulesVersion"
- testImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
- testImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
- testImplementation "androidx.test.ext:truth:$axtTruthVersion"
- testImplementation "androidx.test:core:$axtCoreVersion"
- testImplementation "androidx.fragment:fragment:$fragmentVersion"
- testImplementation "androidx.fragment:fragment-testing:$fragmentVersion"
- testImplementation "androidx.test.ext:junit:$axtJunitVersion"
- testImplementation "com.google.truth:truth:$truthVersion"
+ testImplementation libs.androidx.test.runner
+ testImplementation libs.junit4
+ testImplementation libs.androidx.test.rules
+ testImplementation libs.androidx.test.espresso.intents
+ testImplementation libs.androidx.test.espresso.core
+ testImplementation libs.androidx.test.ext.truth
+ testImplementation libs.androidx.test.core
+ testImplementation libs.androidx.fragment
+ testImplementation libs.androidx.fragment.testing
+ testImplementation libs.androidx.test.ext.junit
+ testImplementation libs.truth
androidTestImplementation project(':annotations')
- androidTestImplementation "androidx.test:runner:$axtRunnerVersion"
- androidTestImplementation "junit:junit:$junitVersion"
- androidTestImplementation "androidx.test:rules:$axtRulesVersion"
- androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
- androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
- androidTestImplementation "androidx.test.ext:truth:$axtTruthVersion"
- androidTestImplementation "androidx.test:core:$axtCoreVersion"
- androidTestImplementation "androidx.test.ext:junit:$axtJunitVersion"
- androidTestImplementation "com.google.truth:truth:$truthVersion"
- androidTestUtil "androidx.test.services:test-services:$axtTestServicesVersion"
+ androidTestImplementation libs.androidx.test.runner
+ androidTestImplementation libs.junit4
+ androidTestImplementation libs.androidx.test.rules
+ androidTestImplementation libs.androidx.test.espresso.intents
+ androidTestImplementation libs.androidx.test.espresso.core
+ androidTestImplementation libs.androidx.test.ext.truth
+ androidTestImplementation libs.androidx.test.core
+ androidTestImplementation libs.androidx.test.ext.junit
+ androidTestImplementation libs.truth
+ androidTestUtil libs.androidx.test.services
}
diff --git a/integration_tests/compat-target28/build.gradle b/integration_tests/compat-target28/build.gradle
index 37a856856..1fc7485ae 100644
--- a/integration_tests/compat-target28/build.gradle
+++ b/integration_tests/compat-target28/build.gradle
@@ -14,6 +14,7 @@ spotless {
android {
compileSdk 28
+ namespace 'org.robolectric.integrationtests.compattarget28'
defaultConfig {
minSdk 16
@@ -30,10 +31,10 @@ android {
}
dependencies {
- implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
+ implementation libs.kotlin.stdlib
testImplementation project(path: ':testapp')
testImplementation project(":robolectric")
- testImplementation "junit:junit:$junitVersion"
- testImplementation "com.google.truth:truth:$truthVersion"
+ testImplementation libs.junit4
+ testImplementation libs.truth
}
diff --git a/integration_tests/compat-target28/src/test/java/org/robolectric/integration/compat/target28/NormalCompatibilityTest.kt b/integration_tests/compat-target28/src/test/java/org/robolectric/integration/compat/target28/NormalCompatibilityTest.kt
index ee56fc6d2..69bbf73e0 100644
--- a/integration_tests/compat-target28/src/test/java/org/robolectric/integration/compat/target28/NormalCompatibilityTest.kt
+++ b/integration_tests/compat-target28/src/test/java/org/robolectric/integration/compat/target28/NormalCompatibilityTest.kt
@@ -1,7 +1,9 @@
package org.robolectric.integration.compat.target28
import android.content.Context
+import android.content.Context.VIBRATOR_SERVICE
import android.os.Build
+import android.os.Vibrator
import android.speech.SpeechRecognizer
import com.google.common.truth.Truth.assertThat
import org.junit.Test
@@ -47,4 +49,9 @@ class NormalCompatibilityTest {
fun `Create speech recognizer succeed`() {
assertThat(SpeechRecognizer.createSpeechRecognizer(application)).isNotNull()
}
+
+ @Test
+ fun `Get default Vibrator succeed`() {
+ assertThat(application.getSystemService(VIBRATOR_SERVICE) as Vibrator).isNotNull()
+ }
}
diff --git a/integration_tests/ctesque/build.gradle b/integration_tests/ctesque/build.gradle
index 3efa7d1b0..3b40c88de 100644
--- a/integration_tests/ctesque/build.gradle
+++ b/integration_tests/ctesque/build.gradle
@@ -7,6 +7,7 @@ apply plugin: GradleManagedDevicePlugin
android {
compileSdk 33
+ namespace 'org.robolectric.integrationtests.ctesque'
defaultConfig {
minSdk 16
@@ -48,26 +49,26 @@ dependencies {
implementation project(':testapp')
testImplementation project(':robolectric')
- testImplementation "junit:junit:${junitVersion}"
- testImplementation("androidx.test:monitor:$axtMonitorVersion")
- testImplementation("androidx.test:runner:$axtRunnerVersion")
- testImplementation("androidx.test:rules:$axtRulesVersion")
- testImplementation("androidx.test.ext:junit:$axtJunitVersion")
- testImplementation("androidx.test.ext:truth:$axtTruthVersion")
- testImplementation("androidx.test:core:$axtCoreVersion")
- testImplementation("androidx.test.espresso:espresso-core:$espressoVersion")
- testImplementation("com.google.truth:truth:${truthVersion}")
- testImplementation("com.google.guava:guava:$guavaJREVersion")
+ testImplementation libs.junit4
+ testImplementation libs.androidx.test.monitor
+ testImplementation libs.androidx.test.runner
+ testImplementation libs.androidx.test.rules
+ testImplementation libs.androidx.test.ext.junit
+ testImplementation libs.androidx.test.ext.truth
+ testImplementation libs.androidx.test.core
+ testImplementation libs.androidx.test.espresso.core
+ testImplementation libs.truth
+ testImplementation libs.guava
// Testing dependencies
androidTestImplementation project(':shadowapi')
- androidTestImplementation("androidx.test:monitor:$axtMonitorVersion")
- androidTestImplementation("androidx.test:runner:$axtRunnerVersion")
- androidTestImplementation("androidx.test:rules:$axtRulesVersion")
- androidTestImplementation("androidx.test.ext:junit:$axtJunitVersion")
- androidTestImplementation("androidx.test.ext:truth:$axtTruthVersion")
- androidTestImplementation("androidx.test.espresso:espresso-core:$espressoVersion")
- androidTestImplementation("com.google.truth:truth:${truthVersion}")
- androidTestImplementation("com.google.guava:guava:$guavaJREVersion")
- androidTestUtil "androidx.test.services:test-services:$axtTestServicesVersion"
+ androidTestImplementation libs.androidx.test.monitor
+ androidTestImplementation libs.androidx.test.runner
+ androidTestImplementation libs.androidx.test.rules
+ androidTestImplementation libs.androidx.test.ext.junit
+ androidTestImplementation libs.androidx.test.ext.truth
+ androidTestImplementation libs.androidx.test.espresso.core
+ androidTestImplementation libs.truth
+ androidTestImplementation libs.guava
+ androidTestUtil libs.androidx.test.services
}
diff --git a/integration_tests/dependency-on-stubs/build.gradle b/integration_tests/dependency-on-stubs/build.gradle
index 6efe51373..683de182d 100644
--- a/integration_tests/dependency-on-stubs/build.gradle
+++ b/integration_tests/dependency-on-stubs/build.gradle
@@ -6,13 +6,13 @@ apply plugin: RoboJavaModulePlugin
dependencies {
api project(":robolectric")
- api "junit:junit:${junitVersion}"
+ api libs.junit4
testImplementation files("${System.getenv("ANDROID_HOME")}/platforms/android-29/android.jar")
testCompileOnly AndroidSdk.MAX_SDK.coordinates // compile against latest Android SDK
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation "org.mockito:mockito-core:${mockitoVersion}"
- testImplementation "org.hamcrest:hamcrest-junit:2.0.0.0"
+ testImplementation libs.truth
+ testImplementation libs.mockito
+ testImplementation libs.hamcrest.junit
}
diff --git a/integration_tests/jacoco-offline/build.gradle b/integration_tests/jacoco-offline/build.gradle
index e5d3bb5eb..3db34c00a 100644
--- a/integration_tests/jacoco-offline/build.gradle
+++ b/integration_tests/jacoco-offline/build.gradle
@@ -3,6 +3,8 @@ import org.robolectric.gradle.RoboJavaModulePlugin
apply plugin: RoboJavaModulePlugin
apply plugin: "jacoco"
+def jacocoVersion = libs.versions.jacoco.get()
+
jacoco {
toolVersion = jacocoVersion
}
@@ -18,7 +20,7 @@ dependencies {
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
testImplementation project(":robolectric")
- testImplementation "junit:junit:$junitVersion"
+ testImplementation libs.junit4
testImplementation "org.jacoco:org.jacoco.agent:$jacocoVersion:runtime"
}
diff --git a/integration_tests/kotlin/build.gradle b/integration_tests/kotlin/build.gradle
index 68c5c677f..fd52d973d 100644
--- a/integration_tests/kotlin/build.gradle
+++ b/integration_tests/kotlin/build.gradle
@@ -21,8 +21,8 @@ dependencies {
testCompileOnly AndroidSdk.MAX_SDK.coordinates
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
- testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
- testImplementation "junit:junit:$junitVersion"
- testImplementation "com.google.truth:truth:$truthVersion"
+ testImplementation libs.kotlin.stdlib
+ testImplementation libs.junit4
+ testImplementation libs.truth
testImplementation "androidx.test:core:$axtCoreVersion@aar"
}
diff --git a/integration_tests/kotlin/src/test/kotlin/org/robolectric/integrationtests/kotlin/ParameterizedRobolectricTestRunnerTest.kt b/integration_tests/kotlin/src/test/kotlin/org/robolectric/integrationtests/kotlin/ParameterizedRobolectricTestRunnerTest.kt
new file mode 100644
index 000000000..6d77aa91f
--- /dev/null
+++ b/integration_tests/kotlin/src/test/kotlin/org/robolectric/integrationtests/kotlin/ParameterizedRobolectricTestRunnerTest.kt
@@ -0,0 +1,28 @@
+package org.robolectric.integrationtests.kotlin
+
+import android.net.Uri
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.ParameterizedRobolectricTestRunner
+import org.robolectric.ParameterizedRobolectricTestRunner.Parameters
+import org.robolectric.annotation.Config
+
+@RunWith(ParameterizedRobolectricTestRunner::class)
+class ParameterizedRobolectricTestRunnerTest(private var uri: Uri) {
+ @Test
+ @Config(manifest = Config.NONE)
+ fun parse() {
+ val currentUri = Uri.parse("http://host/")
+ assertThat(currentUri).isEqualTo(uri)
+ }
+
+ companion object {
+ @Parameters
+ @JvmStatic
+ fun getTestData(): Collection<*> {
+ val data = arrayOf<Any>(Uri.parse("http://host/"))
+ return listOf(data)
+ }
+ }
+}
diff --git a/integration_tests/libphonenumber/build.gradle b/integration_tests/libphonenumber/build.gradle
index 2c27a7968..61120f227 100644
--- a/integration_tests/libphonenumber/build.gradle
+++ b/integration_tests/libphonenumber/build.gradle
@@ -4,10 +4,10 @@ apply plugin: RoboJavaModulePlugin
dependencies {
api project(":robolectric")
- api "junit:junit:${junitVersion}"
+ api libs.junit4
compileOnly AndroidSdk.MAX_SDK.coordinates
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation 'com.googlecode.libphonenumber:libphonenumber:8.13.8'
-} \ No newline at end of file
+ testImplementation libs.truth
+ testImplementation libs.libphonenumber
+}
diff --git a/integration_tests/memoryleaks/build.gradle b/integration_tests/memoryleaks/build.gradle
index 2cc51247c..91c5eb01e 100644
--- a/integration_tests/memoryleaks/build.gradle
+++ b/integration_tests/memoryleaks/build.gradle
@@ -5,6 +5,7 @@ apply plugin: AndroidProjectConfigPlugin
android {
compileSdk 33
+ namespace 'org.robolectric.integrationtests.memoryleaks'
defaultConfig {
minSdk 16
@@ -28,7 +29,7 @@ dependencies {
// Testing dependencies
testImplementation project(path: ':testapp')
testImplementation project(":robolectric")
- testImplementation "junit:junit:$junitVersion"
- testImplementation "com.google.guava:guava-testlib:$guavaJREVersion"
- testImplementation "androidx.fragment:fragment:$fragmentVersion"
+ testImplementation libs.junit4
+ testImplementation libs.guava.testlib
+ testImplementation libs.androidx.fragment
}
diff --git a/integration_tests/mockito-experimental/build.gradle b/integration_tests/mockito-experimental/build.gradle
index 4aafcbc08..f5172d6af 100644
--- a/integration_tests/mockito-experimental/build.gradle
+++ b/integration_tests/mockito-experimental/build.gradle
@@ -8,7 +8,7 @@ dependencies {
testCompileOnly AndroidSdk.MAX_SDK.coordinates
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation "org.mockito:mockito-inline:${mockitoVersion}"
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.mockito.inline
}
diff --git a/integration_tests/mockito-kotlin/build.gradle b/integration_tests/mockito-kotlin/build.gradle
index ae97f1b7a..776f33bd2 100644
--- a/integration_tests/mockito-kotlin/build.gradle
+++ b/integration_tests/mockito-kotlin/build.gradle
@@ -18,8 +18,8 @@ dependencies {
testCompileOnly AndroidSdk.MAX_SDK.coordinates
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
testImplementation "androidx.test.ext:junit:$axtJunitVersion@aar"
- testImplementation "junit:junit:$junitVersion"
- testImplementation "com.google.truth:truth:$truthVersion"
- testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
- testImplementation "org.mockito:mockito-core:$mockitoVersion"
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.kotlin.stdlib
+ testImplementation libs.mockito
}
diff --git a/integration_tests/mockito/build.gradle b/integration_tests/mockito/build.gradle
index e199cd74d..31e6ce675 100644
--- a/integration_tests/mockito/build.gradle
+++ b/integration_tests/mockito/build.gradle
@@ -8,7 +8,7 @@ dependencies {
testCompileOnly AndroidSdk.MAX_SDK.coordinates
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation "org.mockito:mockito-core:${mockitoVersion}"
-} \ No newline at end of file
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.mockito
+}
diff --git a/integration_tests/mockk/build.gradle b/integration_tests/mockk/build.gradle
index 78344a9aa..1d590714e 100644
--- a/integration_tests/mockk/build.gradle
+++ b/integration_tests/mockk/build.gradle
@@ -21,7 +21,7 @@ dependencies {
testCompileOnly AndroidSdk.MAX_SDK.coordinates
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation 'io.mockk:mockk:1.13.4'
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.mockk
}
diff --git a/integration_tests/nativegraphics/build.gradle b/integration_tests/nativegraphics/build.gradle
index 10e8f6138..f88f53a3f 100644
--- a/integration_tests/nativegraphics/build.gradle
+++ b/integration_tests/nativegraphics/build.gradle
@@ -7,6 +7,7 @@ apply plugin: GradleManagedDevicePlugin
android {
compileSdk 33
+ namespace 'org.robolectric.integrationtests.nativegraphics'
defaultConfig {
minSdk 26
@@ -32,9 +33,9 @@ dependencies {
testImplementation AndroidSdk.MAX_SDK.coordinates
testImplementation project(':robolectric')
- testImplementation "androidx.core:core:$coreVersion"
- testImplementation "androidx.test.ext:junit:$axtJunitVersion"
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "org.mockito:mockito-core:${mockitoVersion}"
+ testImplementation libs.androidx.core
+ testImplementation libs.androidx.test.ext.junit
+ testImplementation libs.truth
+ testImplementation libs.junit4
+ testImplementation libs.mockito
}
diff --git a/integration_tests/play_services/build.gradle b/integration_tests/play_services/build.gradle
index f7499dd73..0e05dd6b3 100644
--- a/integration_tests/play_services/build.gradle
+++ b/integration_tests/play_services/build.gradle
@@ -9,7 +9,7 @@ dependencies {
testCompileOnly AndroidSdk.MAX_SDK.coordinates
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
- testImplementation "junit:junit:$junitVersion"
- testImplementation "com.google.truth:truth:$truthVersion"
+ testImplementation libs.junit4
+ testImplementation libs.truth
testImplementation "com.google.android.gms:play-services-basement:18.0.1"
-} \ No newline at end of file
+}
diff --git a/integration_tests/powermock/build.gradle b/integration_tests/powermock/build.gradle
index be4180cf5..6d5cf689d 100644
--- a/integration_tests/powermock/build.gradle
+++ b/integration_tests/powermock/build.gradle
@@ -7,11 +7,8 @@ dependencies {
compileOnly AndroidSdk.MAX_SDK.coordinates
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
+ testImplementation libs.junit4
+ testImplementation libs.truth
- testImplementation "org.powermock:powermock-module-junit4:2.0.9"
- testImplementation "org.powermock:powermock-module-junit4-rule:2.0.9"
- testImplementation "org.powermock:powermock-api-mockito2:2.0.9"
- testImplementation "org.powermock:powermock-classloading-xstream:2.0.9"
-} \ No newline at end of file
+ testImplementation libs.bundles.powermock
+}
diff --git a/integration_tests/security-providers/build.gradle b/integration_tests/security-providers/build.gradle
index f96df56b9..8ac0264a8 100644
--- a/integration_tests/security-providers/build.gradle
+++ b/integration_tests/security-providers/build.gradle
@@ -4,12 +4,12 @@ apply plugin: RoboJavaModulePlugin
dependencies {
api project(":robolectric")
- api "junit:junit:${junitVersion}"
+ api libs.junit4
compileOnly AndroidSdk.MAX_SDK.coordinates
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation "org.conscrypt:conscrypt-openjdk-uber:2.4.0"
- testImplementation "com.squareup.okhttp3:okhttp"
- testImplementation platform("com.squareup.okhttp3:okhttp-bom:4.10.0")
+ testImplementation libs.truth
+ testImplementation libs.conscrypt.openjdk.uber
+ testImplementation libs.okhttp
+ testImplementation platform(libs.okhttp.bom)
}
diff --git a/integration_tests/sparsearray/build.gradle b/integration_tests/sparsearray/build.gradle
index 762717794..1e4ba1ddf 100644
--- a/integration_tests/sparsearray/build.gradle
+++ b/integration_tests/sparsearray/build.gradle
@@ -14,6 +14,7 @@ spotless {
android {
compileSdk 33
+ namespace 'org.robolectric.sparsearray'
defaultConfig {
minSdk 16
@@ -41,7 +42,7 @@ dependencies {
testCompileOnly AndroidSdk.MAX_SDK.coordinates
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
testImplementation project(":robolectric")
- testImplementation "junit:junit:$junitVersion"
- testImplementation "com.google.truth:truth:$truthVersion"
- testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.kotlin.stdlib
}
diff --git a/junit/build.gradle b/junit/build.gradle
index 9a1197871..5d5855254 100644
--- a/junit/build.gradle
+++ b/junit/build.gradle
@@ -11,6 +11,6 @@ dependencies {
api project(":shadowapi")
api project(":utils:reflector")
- compileOnly "com.google.code.findbugs:jsr305:3.0.2"
- compileOnly "junit:junit:${junitVersion}"
+ compileOnly libs.findbugs.jsr305
+ compileOnly libs.junit4
}
diff --git a/nativeruntime/build.gradle b/nativeruntime/build.gradle
index f8d496d5b..646613fa1 100644
--- a/nativeruntime/build.gradle
+++ b/nativeruntime/build.gradle
@@ -64,17 +64,17 @@ if (System.getenv('PUBLISH_NATIVERUNTIME_DIST_COMPAT') == "true") {
dependencies {
api project(":utils")
api project(":utils:reflector")
- api "com.google.guava:guava:$guavaJREVersion"
+ api libs.guava
- implementation "org.robolectric:nativeruntime-dist-compat:1.0.1"
+ implementation libs.robolectric.nativeruntime.dist.compat
- annotationProcessor "com.google.auto.service:auto-service:$autoServiceVersion"
- compileOnly "com.google.auto.service:auto-service-annotations:$autoServiceVersion"
+ annotationProcessor libs.auto.service
+ compileOnly libs.auto.service.annotations
compileOnly AndroidSdk.MAX_SDK.coordinates
testCompileOnly AndroidSdk.MAX_SDK.coordinates
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
testImplementation project(":robolectric")
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
+ testImplementation libs.junit4
+ testImplementation libs.truth
}
diff --git a/nativeruntime/src/test/java/org/robolectric/nativeruntime/DefaultNativeRuntimeLoaderTest.java b/nativeruntime/src/test/java/org/robolectric/nativeruntime/DefaultNativeRuntimeLoaderTest.java
index 03911593e..e5d395f2e 100644
--- a/nativeruntime/src/test/java/org/robolectric/nativeruntime/DefaultNativeRuntimeLoaderTest.java
+++ b/nativeruntime/src/test/java/org/robolectric/nativeruntime/DefaultNativeRuntimeLoaderTest.java
@@ -2,7 +2,7 @@ package org.robolectric.nativeruntime;
import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assume.assumeTrue;
+import static com.google.common.truth.TruthJUnit.assume;
import android.database.CursorWindow;
import android.database.sqlite.SQLiteDatabase;
@@ -33,8 +33,8 @@ public final class DefaultNativeRuntimeLoaderTest {
@Test
public void extracts_fontsAndIcuData() {
- assumeTrue(hasResource("fonts"));
- assumeTrue(hasResource("icu/icudt68l.dat"));
+ assume().that(hasResource("fonts")).isTrue();
+ assume().that(hasResource("icu/icudt68l.dat")).isTrue();
DefaultNativeRuntimeLoader defaultNativeRuntimeLoader = new DefaultNativeRuntimeLoader();
defaultNativeRuntimeLoader.ensureLoaded();
// Check that extraction of some key files worked.
diff --git a/pluginapi/build.gradle b/pluginapi/build.gradle
index 375cd10e4..9d7885291 100644
--- a/pluginapi/build.gradle
+++ b/pluginapi/build.gradle
@@ -5,11 +5,11 @@ apply plugin: RoboJavaModulePlugin
apply plugin: DeployedRoboJavaModulePlugin
dependencies {
- compileOnly 'com.google.code.findbugs:jsr305:3.0.2'
+ compileOnly libs.findbugs.jsr305
api project(":annotations")
- api "com.google.guava:guava:$guavaJREVersion"
+ api libs.guava
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation "org.mockito:mockito-core:${mockitoVersion}"
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.mockito
}
diff --git a/plugins/maven-dependency-resolver/build.gradle b/plugins/maven-dependency-resolver/build.gradle
index de20b2b8f..2aa33d9f5 100644
--- a/plugins/maven-dependency-resolver/build.gradle
+++ b/plugins/maven-dependency-resolver/build.gradle
@@ -1,3 +1,4 @@
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.robolectric.gradle.DeployedRoboJavaModulePlugin
import org.robolectric.gradle.RoboJavaModulePlugin
@@ -13,7 +14,7 @@ spotless {
}
}
-tasks.withType(GenerateModuleMetadata) {
+tasks.withType(GenerateModuleMetadata).configureEach {
// We don't want to release gradle module metadata now to avoid
// potential compatibility problems.
enabled = false
@@ -22,11 +23,11 @@ tasks.withType(GenerateModuleMetadata) {
compileKotlin {
// Use java/main classes directory to replace default kotlin/main to
// avoid d8 error when dexing & desugaring kotlin classes with non-exist
- // kotlin/main directory because utils module doesn't have kotlin code
+ // kotlin/main directory because this module doesn't have kotlin code
// in production. If utils module starts to add Kotlin code in main source
// set, we can remove this destinationDirectory modification.
destinationDirectory = file("${projectDir}/build/classes/java/main")
- compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8
+ compilerOptions.jvmTarget = JvmTarget.JVM_1_8
}
afterEvaluate {
@@ -48,10 +49,12 @@ afterEvaluate {
dependencies {
api project(":pluginapi")
api project(":utils")
- api "com.google.guava:guava:$guavaJREVersion"
+ api libs.auto.value.annotations
+ api libs.guava
+ annotationProcessor libs.auto.value
- testImplementation "junit:junit:$junitVersion"
- testImplementation "org.mockito:mockito-core:$mockitoVersion"
- testImplementation "com.google.truth:truth:$truthVersion"
- testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
+ testImplementation libs.junit4
+ testImplementation libs.mockito
+ testImplementation libs.truth
+ testImplementation libs.kotlin.stdlib
}
diff --git a/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenArtifactFetcher.java b/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenArtifactFetcher.java
index 60f852dbc..adeda9e78 100644
--- a/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenArtifactFetcher.java
+++ b/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenArtifactFetcher.java
@@ -2,6 +2,7 @@ package org.robolectric.internal.dependency;
import static java.nio.charset.StandardCharsets.UTF_8;
+import com.google.auto.value.AutoValue;
import com.google.common.base.Strings;
import com.google.common.hash.HashCode;
import com.google.common.hash.Hashing;
@@ -24,6 +25,7 @@ import java.net.URLConnection;
import java.util.Base64;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
+import javax.annotation.Nonnull;
import org.robolectric.util.Logger;
/**
@@ -82,15 +84,27 @@ public class MavenArtifactFetcher {
return Futures.immediateFuture(null);
}
createArtifactSubdirectory(artifact, localRepositoryDir);
- boolean pomValid =
+ ValidationResult pomResult =
validateStagedFiles(artifact.pomPath(), artifact.pomSha512Path());
- if (!pomValid) {
- throw new AssertionError("SHA512 mismatch for POM file fetched in " + artifact);
+ if (!pomResult.isSuccess()) {
+ throw new AssertionError(
+ "SHA-512 mismatch for POM file for "
+ + artifact
+ + ", expected SHA-512="
+ + pomResult.expectedHashCode()
+ + ", actual SHA-512="
+ + pomResult.calculatedHashCode());
}
- boolean jarValid =
+ ValidationResult jarResult =
validateStagedFiles(artifact.jarPath(), artifact.jarSha512Path());
- if (!jarValid) {
- throw new AssertionError("SHA512 mismatch for JAR file fetched in " + artifact);
+ if (!jarResult.isSuccess()) {
+ throw new AssertionError(
+ "SHA-512 mismatch for POM file for "
+ + artifact
+ + ", expected SHA-512="
+ + jarResult.expectedHashCode()
+ + ", actual SHA-512="
+ + jarResult.calculatedHashCode());
}
Logger.info(
String.format(
@@ -123,7 +137,8 @@ public class MavenArtifactFetcher {
new File(repositoryDir, artifact.pomSha512Path()).delete();
}
- private boolean validateStagedFiles(String filePath, String sha512Path) throws IOException {
+ private ValidationResult validateStagedFiles(String filePath, String sha512Path)
+ throws IOException {
File tempFile = new File(this.stagingRepositoryDir, filePath);
File sha512File = new File(this.stagingRepositoryDir, sha512Path);
@@ -131,7 +146,24 @@ public class MavenArtifactFetcher {
HashCode.fromString(new String(Files.asByteSource(sha512File).read(), UTF_8));
HashCode actual = Files.asByteSource(tempFile).hash(Hashing.sha512());
- return expected.equals(actual);
+ return ValidationResult.create(expected.equals(actual), expected.toString(), actual.toString());
+ }
+
+ @AutoValue
+ abstract static class ValidationResult {
+ abstract boolean isSuccess();
+
+ @Nonnull
+ abstract String expectedHashCode();
+
+ @Nonnull
+ abstract String calculatedHashCode();
+
+ static ValidationResult create(
+ boolean isSuccess, String expectedHashCode, String calculatedHashCode) {
+ return new AutoValue_MavenArtifactFetcher_ValidationResult(
+ isSuccess, expectedHashCode, calculatedHashCode);
+ }
}
private void createArtifactSubdirectory(MavenJarArtifact artifact, File repositoryDir)
@@ -218,6 +250,9 @@ public class MavenArtifactFetcher {
try (InputStream inputStream = connection.getInputStream();
FileOutputStream outputStream = new FileOutputStream(localFile)) {
ByteStreams.copy(inputStream, outputStream);
+ // Ensure all contents are written to disk.
+ outputStream.flush();
+ outputStream.getFD().sync();
}
return Futures.immediateFuture(null);
}
diff --git a/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenDependencyResolver.java b/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenDependencyResolver.java
index bb5604d80..bb5604d80 100755..100644
--- a/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenDependencyResolver.java
+++ b/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenDependencyResolver.java
diff --git a/preinstrumented/build.gradle b/preinstrumented/build.gradle
index 95d533e4d..c489a115a 100644
--- a/preinstrumented/build.gradle
+++ b/preinstrumented/build.gradle
@@ -17,11 +17,11 @@ java {
}
dependencies {
- implementation "com.google.guava:guava:$guavaJREVersion"
+ implementation libs.guava
implementation project(":sandbox")
}
-task instrumentAll {
+tasks.register('instrumentAll') {
dependsOn ':prefetchSdks'
dependsOn 'build'
@@ -42,11 +42,11 @@ task instrumentAll {
}
}
-task('sourcesJar', type: Jar) {
+tasks.register('sourcesJar', Jar) {
archiveClassifier = "sources"
}
-task('javadocJar', type: Jar) {
+tasks.register('javadocJar', Jar) {
archiveClassifier = "javadoc"
}
@@ -132,4 +132,4 @@ clean.doFirst {
AndroidSdk.ALL_SDKS.each { androidSdk ->
delete "${buildDir}/${androidSdk.preinstrumentedJarFileName}"
}
-} \ No newline at end of file
+}
diff --git a/processor/build.gradle b/processor/build.gradle
index ac14e4282..9185d088a 100644
--- a/processor/build.gradle
+++ b/processor/build.gradle
@@ -35,21 +35,21 @@ dependencies {
api project(":annotations")
api project(":shadowapi")
- compileOnly "com.google.code.findbugs:jsr305:3.0.2"
- api "org.ow2.asm:asm:${asmVersion}"
- api "org.ow2.asm:asm-commons:${asmVersion}"
- api "com.google.guava:guava:$guavaJREVersion"
- api "com.google.code.gson:gson:2.10.1"
- implementation 'com.google.auto:auto-common:1.1.2'
+ compileOnly libs.findbugs.jsr305
+ api libs.asm
+ api libs.asm.commons
+ api libs.guava
+ api libs.gson
+ implementation libs.auto.common
def toolsJar = Jvm.current().getToolsJar()
if (toolsJar != null) {
implementation files(toolsJar)
}
- testImplementation "javax.annotation:jsr250-api:1.0"
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "org.mockito:mockito-core:${mockitoVersion}"
- testImplementation "com.google.testing.compile:compile-testing:0.21.0"
- testImplementation "com.google.truth:truth:${truthVersion}"
+ testImplementation libs.javax.annotation.jsr250.api
+ testImplementation libs.junit4
+ testImplementation libs.mockito
+ testImplementation libs.compile.testing
+ testImplementation libs.truth
}
diff --git a/resources/build.gradle b/resources/build.gradle
index 129dc20ad..077cdd3b3 100644
--- a/resources/build.gradle
+++ b/resources/build.gradle
@@ -9,11 +9,11 @@ dependencies {
api project(":annotations")
api project(":pluginapi")
- api "com.google.guava:guava:$guavaJREVersion"
- compileOnly "com.google.code.findbugs:jsr305:3.0.2"
+ api libs.guava
+ compileOnly libs.findbugs.jsr305
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation "com.google.testing.compile:compile-testing:0.21.0"
- testImplementation "org.mockito:mockito-core:${mockitoVersion}"
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.compile.testing
+ testImplementation libs.mockito
}
diff --git a/resources/src/main/java/org/robolectric/manifest/AndroidManifest.java b/resources/src/main/java/org/robolectric/manifest/AndroidManifest.java
index cfabcbb2b..7402b4982 100644
--- a/resources/src/main/java/org/robolectric/manifest/AndroidManifest.java
+++ b/resources/src/main/java/org/robolectric/manifest/AndroidManifest.java
@@ -53,6 +53,7 @@ public class AndroidManifest implements UsesSdk {
private String processName;
private String themeRef;
private String labelRef;
+ private String appComponentFactory; // Added from SDK 28
private Integer minSdkVersion;
private Integer targetSdkVersion;
private Integer maxSdkVersion;
@@ -191,6 +192,7 @@ public class AndroidManifest implements UsesSdk {
rClassName = packageName + ".R";
Node applicationNode = findApplicationNode(manifestDocument);
+ // Parse application node of the AndroidManifest.xml
if (applicationNode != null) {
NamedNodeMap attributes = applicationNode.getAttributes();
int attrCount = attributes.getLength();
@@ -204,6 +206,7 @@ public class AndroidManifest implements UsesSdk {
processName = applicationAttributes.get("android:process");
themeRef = applicationAttributes.get("android:theme");
labelRef = applicationAttributes.get("android:label");
+ appComponentFactory = applicationAttributes.get("android:appComponentFactory");
parseReceivers(applicationNode);
parseServices(applicationNode);
@@ -605,6 +608,11 @@ public class AndroidManifest implements UsesSdk {
return labelRef;
}
+ public String getAppComponentFactory() {
+ parseAndroidManifest();
+ return appComponentFactory;
+ }
+
/**
* Returns the minimum Android SDK version that this package expects to be runnable on, as
* specified in the manifest.
diff --git a/robolectric/build.gradle b/robolectric/build.gradle
index faaa8b3a0..b826e9232 100644
--- a/robolectric/build.gradle
+++ b/robolectric/build.gradle
@@ -5,8 +5,8 @@ apply plugin: RoboJavaModulePlugin
apply plugin: DeployedRoboJavaModulePlugin
dependencies {
- annotationProcessor "com.google.auto.service:auto-service:$autoServiceVersion"
- annotationProcessor "com.google.errorprone:error_prone_core:$errorproneVersion"
+ annotationProcessor libs.auto.service
+ annotationProcessor libs.error.prone.core
api project(":annotations")
api project(":junit")
@@ -16,33 +16,34 @@ dependencies {
api project(":utils")
api project(":utils:reflector")
api project(":plugins:maven-dependency-resolver")
- api "javax.inject:javax.inject:1"
- compileOnly "com.google.auto.service:auto-service-annotations:$autoServiceVersion"
- api "javax.annotation:javax.annotation-api:1.3.2"
+ api libs.javax.inject
+ compileOnly libs.auto.service.annotations
+ api libs.javax.annotation.api
// We need to have shadows-framework.jar on the runtime system classpath so ServiceLoader
// can find its META-INF/services/org.robolectric.shadows.ShadowAdapter.
api project(":shadows:framework")
- implementation 'org.conscrypt:conscrypt-openjdk-uber:2.5.2'
- api "org.bouncycastle:bcprov-jdk18on:1.72"
- compileOnly "com.google.code.findbugs:jsr305:3.0.2"
+ implementation libs.conscrypt.openjdk.uber
+ api libs.bcprov.jdk18on
+ compileOnly libs.findbugs.jsr305
compileOnly AndroidSdk.MAX_SDK.coordinates
- compileOnly "junit:junit:${junitVersion}"
+ compileOnly libs.junit4
+
api "androidx.test:monitor:$axtMonitorVersion@aar"
implementation "androidx.test.espresso:espresso-idling-resource:$espressoVersion@aar"
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation "com.google.truth.extensions:truth-java8-extension:${truthVersion}"
- testImplementation "org.mockito:mockito-core:${mockitoVersion}"
- testImplementation "org.hamcrest:hamcrest-junit:2.0.0.0"
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.truth.java8.extension
+ testImplementation libs.mockito
+ testImplementation libs.hamcrest.junit
testImplementation "androidx.test:core:$axtCoreVersion@aar"
testImplementation "androidx.test.ext:junit:$axtJunitVersion@aar"
testImplementation "androidx.test.ext:truth:$axtTruthVersion@aar"
testImplementation "androidx.test:runner:$axtRunnerVersion@aar"
- testImplementation("com.google.guava:guava:$guavaJREVersion")
+ testImplementation libs.guava
testCompileOnly AndroidSdk.MAX_SDK.coordinates // compile against latest Android SDK
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates // run against whatever this JDK supports
}
diff --git a/robolectric/src/main/java/org/robolectric/android/internal/AndroidTestEnvironment.java b/robolectric/src/main/java/org/robolectric/android/internal/AndroidTestEnvironment.java
index c1587fc17..f250381f4 100644
--- a/robolectric/src/main/java/org/robolectric/android/internal/AndroidTestEnvironment.java
+++ b/robolectric/src/main/java/org/robolectric/android/internal/AndroidTestEnvironment.java
@@ -87,6 +87,7 @@ import org.robolectric.shadows.ShadowPackageManager;
import org.robolectric.shadows.ShadowPackageParser;
import org.robolectric.shadows.ShadowPackageParser._Package_;
import org.robolectric.shadows.ShadowView;
+import org.robolectric.util.Logger;
import org.robolectric.util.PerfStatsCollector;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.Scheduler;
@@ -362,7 +363,7 @@ public class AndroidTestEnvironment implements TestEnvironment {
// Preload fonts resources
FontsContract.setApplicationContextForResources(application);
}
- registerBroadcastReceivers(application, appManifest);
+ registerBroadcastReceivers(application, appManifest, loadedApk);
appResources.updateConfiguration(androidConfiguration, displayMetrics);
// propagate any updates to configuration via RuntimeEnvironment.setQualifiers
@@ -413,6 +414,11 @@ public class AndroidTestEnvironment implements TestEnvironment {
Path packageFile = appManifest.getApkFile();
parsedPackage = ShadowPackageParser.callParsePackage(packageFile);
}
+ if (parsedPackage != null
+ && parsedPackage.applicationInfo != null
+ && RuntimeEnvironment.getApiLevel() >= P) {
+ parsedPackage.applicationInfo.appComponentFactory = appManifest.getAppComponentFactory();
+ }
return parsedPackage;
}
@@ -697,15 +703,39 @@ public class AndroidTestEnvironment implements TestEnvironment {
.toString();
}
+ private static BroadcastReceiver newBroadcastReceiverFromP(
+ String receiverClassName, LoadedApk loadedApk) {
+ ClassLoader classLoader = Shadow.class.getClassLoader();
+ if (loadedApk == null || loadedApk.getAppFactory() == null) {
+ return (BroadcastReceiver) newInstanceOf(receiverClassName);
+ } else {
+ try {
+ return loadedApk.getAppFactory().instantiateReceiver(classLoader, receiverClassName, null);
+ } catch (ReflectiveOperationException e) {
+ Logger.warn(
+ "Failed to initialize receiver %s with AppComponentFactory %s: %s",
+ receiverClassName, loadedApk.getAppFactory(), e);
+ }
+ }
+ return null;
+ }
+
// TODO move/replace this with packageManager
@VisibleForTesting
- static void registerBroadcastReceivers(Application application, AndroidManifest androidManifest) {
+ static void registerBroadcastReceivers(
+ Application application, AndroidManifest androidManifest, LoadedApk loadedApk) {
for (BroadcastReceiverData receiver : androidManifest.getBroadcastReceivers()) {
IntentFilter filter = new IntentFilter();
for (String action : receiver.getActions()) {
filter.addAction(action);
}
- application.registerReceiver((BroadcastReceiver) newInstanceOf(receiver.getName()), filter);
+ String receiverClassName = receiver.getName();
+ if (loadedApk != null && RuntimeEnvironment.getApiLevel() >= P) {
+ application.registerReceiver(
+ newBroadcastReceiverFromP(receiverClassName, loadedApk), filter);
+ } else {
+ application.registerReceiver((BroadcastReceiver) newInstanceOf(receiverClassName), filter);
+ }
}
}
diff --git a/robolectric/src/main/java/org/robolectric/internal/AndroidSandbox.java b/robolectric/src/main/java/org/robolectric/internal/AndroidSandbox.java
index 69adb67e6..69adb67e6 100755..100644
--- a/robolectric/src/main/java/org/robolectric/internal/AndroidSandbox.java
+++ b/robolectric/src/main/java/org/robolectric/internal/AndroidSandbox.java
diff --git a/robolectric/src/main/java/org/robolectric/internal/dependency/PropertiesDependencyResolver.java b/robolectric/src/main/java/org/robolectric/internal/dependency/PropertiesDependencyResolver.java
index 837e966e5..837e966e5 100755..100644
--- a/robolectric/src/main/java/org/robolectric/internal/dependency/PropertiesDependencyResolver.java
+++ b/robolectric/src/main/java/org/robolectric/internal/dependency/PropertiesDependencyResolver.java
diff --git a/robolectric/src/test/java/org/robolectric/CustomAppComponentFactory.java b/robolectric/src/test/java/org/robolectric/CustomAppComponentFactory.java
new file mode 100644
index 000000000..22df750a9
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/CustomAppComponentFactory.java
@@ -0,0 +1,22 @@
+package org.robolectric;
+
+import android.app.AppComponentFactory;
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+import org.robolectric.CustomConstructorReceiverWrapper.CustomConstructorWithEmptyActionReceiver;
+import org.robolectric.CustomConstructorReceiverWrapper.CustomConstructorWithOneActionReceiver;
+
+public final class CustomAppComponentFactory extends AppComponentFactory {
+ @Override
+ public BroadcastReceiver instantiateReceiver(ClassLoader cl, String className, Intent intent)
+ throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+ if (className != null) {
+ if (className.contains(CustomConstructorWithOneActionReceiver.class.getName())) {
+ return new CustomConstructorWithOneActionReceiver(100);
+ } else if (className.contains(CustomConstructorWithEmptyActionReceiver.class.getName())) {
+ return new CustomConstructorWithEmptyActionReceiver(100);
+ }
+ }
+ return super.instantiateReceiver(cl, className, intent);
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/CustomConstructorReceiverWrapper.java b/robolectric/src/test/java/org/robolectric/CustomConstructorReceiverWrapper.java
new file mode 100644
index 000000000..1132f6eb7
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/CustomConstructorReceiverWrapper.java
@@ -0,0 +1,32 @@
+package org.robolectric;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class CustomConstructorReceiverWrapper {
+ private static class CustomConstructorReceiver extends BroadcastReceiver {
+ private final int intValue;
+
+ public CustomConstructorReceiver(int intValue) {
+ // We don't use intValue actually, and we only want to use this class to test the
+ // initialization of BroadcastReceiver with a custom constructor.
+ this.intValue = intValue;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {}
+ }
+
+ public static class CustomConstructorWithOneActionReceiver extends CustomConstructorReceiver {
+ public CustomConstructorWithOneActionReceiver(int intValue) {
+ super(intValue);
+ }
+ }
+
+ public static class CustomConstructorWithEmptyActionReceiver extends CustomConstructorReceiver {
+ public CustomConstructorWithEmptyActionReceiver(int intValue) {
+ super(intValue);
+ }
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/android/DrawableResourceLoaderTest.java b/robolectric/src/test/java/org/robolectric/android/DrawableResourceLoaderTest.java
index 87ddb071b..0428c44e1 100644
--- a/robolectric/src/test/java/org/robolectric/android/DrawableResourceLoaderTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/DrawableResourceLoaderTest.java
@@ -3,9 +3,9 @@ package org.robolectric.android;
import static android.os.Build.VERSION_CODES.KITKAT_WATCH;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.TruthJUnit.assume;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assume.assumeTrue;
import static org.robolectric.shadows.ShadowAssetManager.useLegacy;
import android.animation.Animator;
@@ -31,7 +31,7 @@ public class DrawableResourceLoaderTest {
@Before
public void setup() throws Exception {
- assumeTrue(useLegacy());
+ assume().that(useLegacy()).isTrue();
resources = ApplicationProvider.getApplicationContext().getResources();
}
diff --git a/robolectric/src/test/java/org/robolectric/android/ResourceLoaderTest.java b/robolectric/src/test/java/org/robolectric/android/ResourceLoaderTest.java
index b895d6503..15ca52c68 100644
--- a/robolectric/src/test/java/org/robolectric/android/ResourceLoaderTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/ResourceLoaderTest.java
@@ -2,7 +2,7 @@ package org.robolectric.android;
import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assume.assumeTrue;
+import static com.google.common.truth.TruthJUnit.assume;
import static org.robolectric.shadows.ShadowAssetManager.useLegacy;
import android.content.res.Configuration;
@@ -32,7 +32,7 @@ public class ResourceLoaderTest {
@Before
public void setUp() {
- assumeTrue(useLegacy());
+ assume().that(useLegacy()).isTrue();
optsForO = RuntimeEnvironment.getApiLevel() >= O
? "nowidecg-lowdr-"
@@ -71,7 +71,11 @@ public class ResourceLoaderTest {
private void checkForPollutionHelper() {
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);
+ .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(ApplicationProvider.getApplicationContext())
@@ -97,7 +101,10 @@ public class ResourceLoaderTest {
assertThat(resId).isNotNull();
assertThat(resourceProvider.getResName(resId)).isEqualTo(internalResource);
- Class<?> internalRIdClass = Robolectric.class.getClassLoader().loadClass("com.android.internal.R$" + internalResource.type);
+ Class<?> internalRIdClass =
+ Robolectric.class
+ .getClassLoader()
+ .loadClass("com.android.internal.R$" + internalResource.type);
int internalResourceId;
internalResourceId = (Integer) internalRIdClass.getDeclaredField(internalResource.name).get(null);
assertThat(resId).isEqualTo(internalResourceId);
diff --git a/robolectric/src/test/java/org/robolectric/android/ResourceTableFactoryIntegrationTest.java b/robolectric/src/test/java/org/robolectric/android/ResourceTableFactoryIntegrationTest.java
index 0ae467557..d4395c5a7 100644
--- a/robolectric/src/test/java/org/robolectric/android/ResourceTableFactoryIntegrationTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/ResourceTableFactoryIntegrationTest.java
@@ -1,7 +1,7 @@
package org.robolectric.android;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assume.assumeTrue;
+import static com.google.common.truth.TruthJUnit.assume;
import static org.robolectric.shadows.ShadowAssetManager.useLegacy;
import android.os.Build;
@@ -17,7 +17,7 @@ import org.robolectric.res.ResName;
public class ResourceTableFactoryIntegrationTest {
@Test
public void shouldIncludeStyleableAttributesThatDoNotHaveACorrespondingEntryInAttrClass() throws Exception {
- assumeTrue(useLegacy());
+ assume().that(useLegacy()).isTrue();
// This covers a corner case in Framework resources where an attribute is mentioned in a styleable array, e.g: R.styleable.Toolbar_buttonGravity but there is no corresponding R.attr.buttonGravity
assertThat(RuntimeEnvironment.getSystemResourceTable()
.getResourceId(new ResName("android", "attr", "buttonGravity"))).isGreaterThan(0);
diff --git a/robolectric/src/test/java/org/robolectric/android/XmlResourceParserImplTest.java b/robolectric/src/test/java/org/robolectric/android/XmlResourceParserImplTest.java
index b57f606ee..0c8d977d0 100644
--- a/robolectric/src/test/java/org/robolectric/android/XmlResourceParserImplTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/XmlResourceParserImplTest.java
@@ -2,11 +2,11 @@ package org.robolectric.android;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.common.truth.TruthJUnit.assume;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Arrays.asList;
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;
@@ -276,7 +276,7 @@ public class XmlResourceParserImplTest {
@Test
public void testIsWhitespace() throws Exception {
- assumeTrue(RuntimeEnvironment.useLegacyResources());
+ assume().that(RuntimeEnvironment.useLegacyResources()).isTrue();
XmlResourceParserImpl parserImpl = (XmlResourceParserImpl) parser;
assertThat(parserImpl.isWhitespace("bar")).isFalse();
diff --git a/robolectric/src/test/java/org/robolectric/android/internal/AndroidTestEnvironmentCreateApplicationTest.java b/robolectric/src/test/java/org/robolectric/android/internal/AndroidTestEnvironmentCreateApplicationTest.java
index 6edc42886..dc6ac3138 100644
--- a/robolectric/src/test/java/org/robolectric/android/internal/AndroidTestEnvironmentCreateApplicationTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/internal/AndroidTestEnvironmentCreateApplicationTest.java
@@ -88,7 +88,7 @@ public class AndroidTestEnvironmentCreateApplicationTest {
Application application = AndroidTestEnvironment.createApplication(appManifest, null,
new ApplicationInfo());
shadowOf(application).callAttach(RuntimeEnvironment.systemContext);
- registerBroadcastReceivers(application, appManifest);
+ registerBroadcastReceivers(application, appManifest, null);
List<ShadowApplication.Wrapper> receivers = shadowOf(application).getRegisteredReceivers();
assertThat(receivers).hasSize(1);
diff --git a/robolectric/src/test/java/org/robolectric/android/internal/AndroidTestEnvironmentTest.java b/robolectric/src/test/java/org/robolectric/android/internal/AndroidTestEnvironmentTest.java
index 8b5551a08..375699417 100644
--- a/robolectric/src/test/java/org/robolectric/android/internal/AndroidTestEnvironmentTest.java
+++ b/robolectric/src/test/java/org/robolectric/android/internal/AndroidTestEnvironmentTest.java
@@ -2,8 +2,8 @@ package org.robolectric.android.internal;
import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.TruthJUnit.assume;
import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
import static org.robolectric.annotation.ConscryptMode.Mode.OFF;
import static org.robolectric.annotation.ConscryptMode.Mode.ON;
import static org.robolectric.annotation.LooperMode.Mode.LEGACY;
@@ -241,7 +241,7 @@ public class AndroidTestEnvironmentTest {
@Test
public void testResourceNotFound() {
// not relevant for binary resources mode
- assumeTrue(bootstrapWrapper.isLegacyResources());
+ assume().that(bootstrapWrapper.isLegacyResources()).isTrue();
try {
bootstrapWrapper.changeAppManifest(new ThrowingManifest(bootstrapWrapper.getAppManifest()));
diff --git a/robolectric/src/test/java/org/robolectric/interceptors/AndroidInterceptorsIntegrationTest.java b/robolectric/src/test/java/org/robolectric/interceptors/AndroidInterceptorsIntegrationTest.java
index 679b456f2..af1d8ba86 100644
--- a/robolectric/src/test/java/org/robolectric/interceptors/AndroidInterceptorsIntegrationTest.java
+++ b/robolectric/src/test/java/org/robolectric/interceptors/AndroidInterceptorsIntegrationTest.java
@@ -187,6 +187,6 @@ public class AndroidInterceptorsIntegrationTest {
callsite
.dynamicInvoker()
.invokeWithArguments(
- Arrays.stream(params).map(param -> param.val).collect(Collectors.toList()));
+ Arrays.stream(params).map(param -> param.value).collect(Collectors.toList()));
}
}
diff --git a/robolectric/src/test/java/org/robolectric/internal/MavenManifestFactoryTest.java b/robolectric/src/test/java/org/robolectric/internal/MavenManifestFactoryTest.java
index 414fdb09d..414fdb09d 100755..100644
--- a/robolectric/src/test/java/org/robolectric/internal/MavenManifestFactoryTest.java
+++ b/robolectric/src/test/java/org/robolectric/internal/MavenManifestFactoryTest.java
diff --git a/robolectric/src/test/java/org/robolectric/internal/dependency/PropertiesDependencyResolverTest.java b/robolectric/src/test/java/org/robolectric/internal/dependency/PropertiesDependencyResolverTest.java
index f4562f5d2..f4562f5d2 100755..100644
--- a/robolectric/src/test/java/org/robolectric/internal/dependency/PropertiesDependencyResolverTest.java
+++ b/robolectric/src/test/java/org/robolectric/internal/dependency/PropertiesDependencyResolverTest.java
diff --git a/robolectric/src/test/java/org/robolectric/res/StyleResourceLoaderTest.java b/robolectric/src/test/java/org/robolectric/res/StyleResourceLoaderTest.java
index 8b493ba71..dc2026601 100644
--- a/robolectric/src/test/java/org/robolectric/res/StyleResourceLoaderTest.java
+++ b/robolectric/src/test/java/org/robolectric/res/StyleResourceLoaderTest.java
@@ -2,7 +2,7 @@ package org.robolectric.res;
import static android.os.Build.VERSION_CODES.JELLY_BEAN;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assume.assumeTrue;
+import static com.google.common.truth.TruthJUnit.assume;
import static org.robolectric.util.TestUtil.sdkResources;
import org.junit.Before;
@@ -18,14 +18,16 @@ public class StyleResourceLoaderTest {
@Before
public void setUp() throws Exception {
- assumeTrue(RuntimeEnvironment.useLegacyResources());
+ assume().that(RuntimeEnvironment.useLegacyResources()).isTrue();
ResourcePath resourcePath = sdkResources(JELLY_BEAN);
resourceTable = new ResourceTableFactory().newResourceTable("android", resourcePath);
}
@Test
public void testStyleDataIsLoadedCorrectly() throws Exception {
- TypedResource typedResource = resourceTable.getValue(new ResName("android", "style", "Theme_Holo"), new ResTable_config());
+ TypedResource typedResource =
+ resourceTable.getValue(
+ new ResName("android", "style", "Theme_Holo"), new ResTable_config());
StyleData styleData = (StyleData) typedResource.getData();
assertThat(styleData.getName()).isEqualTo("Theme_Holo");
assertThat(styleData.getParent()).isEqualTo("Theme");
diff --git a/robolectric/src/test/java/org/robolectric/shadows/CellIdentityNrBuilderTest.java b/robolectric/src/test/java/org/robolectric/shadows/CellIdentityNrBuilderTest.java
new file mode 100644
index 000000000..8474b2136
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/CellIdentityNrBuilderTest.java
@@ -0,0 +1,90 @@
+package org.robolectric.shadows;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Build;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.CellIdentityNr;
+import android.telephony.CellInfo;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+/** Test for {@link CellIdentityNrBuilder} */
+@RunWith(AndroidJUnit4.class)
+@Config(minSdk = Build.VERSION_CODES.Q)
+public class CellIdentityNrBuilderTest {
+
+ private static final int PCI = 1;
+ private static final int TAC = 2;
+ private static final int NRARFCN = 4;
+ private static final int[] BANDS =
+ new int[] {
+ AccessNetworkConstants.NgranBands.BAND_1, AccessNetworkConstants.NgranBands.BAND_2
+ };
+ private static final String MCC = "310";
+ private static final String MNC = "260";
+ private static final int NCI = 0;
+ private static final String LONG_OPERATOR_NAME = "long operator name";
+ private static final String SHORT_OPERATOR_NAME = "short operator name";
+ private static final ImmutableList<String> ADDITIONAL_PLMNS = ImmutableList.of("310240");
+
+ @Test
+ public void build_noArguments() {
+ // The intent is to primarily verify that there are no issues setting default values i.e., no
+ // exceptions thrown or invalid inputs.
+ CellIdentityNr cellIdentity = CellIdentityNrBuilder.newBuilder().build();
+
+ assertThat(cellIdentity.getPci()).isEqualTo(CellInfo.UNAVAILABLE);
+ }
+
+ @Test
+ @Config(minSdk = Build.VERSION_CODES.Q, maxSdk = Build.VERSION_CODES.R)
+ public void build_sdkQtoR() {
+ CellIdentityNr cellIdentity = getCellIdentityNr();
+
+ assertCellIdentityFieldsForAllSdks(cellIdentity);
+ }
+
+ @Test
+ @Config(minSdk = Build.VERSION_CODES.S)
+ public void build_fromSdkS() {
+ CellIdentityNr cellIdentity = getCellIdentityNr();
+
+ assertCellIdentityFieldsForAllSdks(cellIdentity);
+ assertThat(cellIdentity.getBands()).isEqualTo(BANDS);
+ assertThat(cellIdentity.getAdditionalPlmns()).containsExactlyElementsIn(ADDITIONAL_PLMNS);
+ }
+
+ /**
+ * Assertions on {@link android.telephony.CellIdentityNr} values that are common across all tested
+ * SDKs.
+ */
+ private void assertCellIdentityFieldsForAllSdks(CellIdentityNr cellIdentity) {
+ assertThat(cellIdentity.getPci()).isEqualTo(PCI);
+ assertThat(cellIdentity.getTac()).isEqualTo(TAC);
+ assertThat(cellIdentity.getNrarfcn()).isEqualTo(NRARFCN);
+ assertThat(cellIdentity.getMccString()).isEqualTo(MCC);
+ assertThat(cellIdentity.getMncString()).isEqualTo(MNC);
+ assertThat(cellIdentity.getNci()).isEqualTo(NCI);
+ assertThat(cellIdentity.getOperatorAlphaLong().toString()).isEqualTo(LONG_OPERATOR_NAME);
+ assertThat(cellIdentity.getOperatorAlphaShort().toString()).isEqualTo(SHORT_OPERATOR_NAME);
+ }
+
+ private CellIdentityNr getCellIdentityNr() {
+ return CellIdentityNrBuilder.newBuilder()
+ .setPci(PCI)
+ .setTac(TAC)
+ .setNrarfcn(NRARFCN)
+ .setBands(BANDS)
+ .setMcc(MCC)
+ .setMnc(MNC)
+ .setNci(NCI)
+ .setLongOperatorName(LONG_OPERATOR_NAME)
+ .setShortOperatorName(SHORT_OPERATOR_NAME)
+ .setAdditionalPlmns(ADDITIONAL_PLMNS)
+ .build();
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/CellInfoNrBuilderTest.java b/robolectric/src/test/java/org/robolectric/shadows/CellInfoNrBuilderTest.java
new file mode 100644
index 000000000..80e7dcc6e
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/CellInfoNrBuilderTest.java
@@ -0,0 +1,76 @@
+package org.robolectric.shadows;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Build;
+import android.telephony.CellIdentityNr;
+import android.telephony.CellInfoNr;
+import android.telephony.CellSignalStrengthNr;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import java.time.Duration;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+/** Test for {@link CellInfoNrBuilder} */
+@RunWith(AndroidJUnit4.class)
+@Config(minSdk = Build.VERSION_CODES.Q)
+public class CellInfoNrBuilderTest {
+
+ private static final boolean REGISTERED = false;
+ private static final long TIMESTAMP_NANOS = 123L;
+ private static final long TIMESTAMP_MILLIS = Duration.ofNanos(TIMESTAMP_NANOS).toMillis();
+ private static final int CELL_CONNECTION_STATUS = 1;
+
+ private static final CellIdentityNr cellIdentity =
+ CellIdentityNrBuilder.newBuilder().setMcc("310").build();
+ private static final CellSignalStrengthNr cellSignalStrength =
+ CellSignalStrengthNrBuilder.newBuilder().setCsiRsrp(-100).build();
+
+ @Test
+ public void build_noArguments() {
+ // The intent is to primarily verify that there are no issues setting default values i.e., no
+ // exceptions thrown or invalid inputs.
+ CellInfoNr cellInfo = CellInfoNrBuilder.newBuilder().build();
+
+ assertThat(cellInfo.getTimeStamp()).isEqualTo(0);
+ }
+
+ @Test
+ @Config(sdk = Build.VERSION_CODES.Q)
+ public void build_sdkQ() {
+ CellInfoNr cellInfo = getCellInfoNr();
+
+ assertCellInfoFieldsForAllSdks(cellInfo);
+ }
+
+ @Test
+ @Config(minSdk = Build.VERSION_CODES.R)
+ public void build_fromSdkR() {
+ CellInfoNr cellInfo = getCellInfoNr();
+
+ assertCellInfoFieldsForAllSdks(cellInfo);
+ assertThat(cellInfo.getTimestampMillis()).isEqualTo(TIMESTAMP_MILLIS);
+ }
+
+ /**
+ * Assertions on {@link android.telephony.CellInfo} values that are common across all tested SDKs.
+ */
+ private void assertCellInfoFieldsForAllSdks(CellInfoNr cellInfo) {
+ assertThat(cellInfo.isRegistered()).isFalse();
+ assertThat(cellInfo.getTimeStamp()).isEqualTo(TIMESTAMP_NANOS);
+ assertThat(cellInfo.getCellConnectionStatus()).isEqualTo(CELL_CONNECTION_STATUS);
+ assertThat(cellInfo.getCellIdentity()).isEqualTo(cellIdentity);
+ assertThat(cellInfo.getCellSignalStrength()).isEqualTo(cellSignalStrength);
+ }
+
+ private CellInfoNr getCellInfoNr() {
+ return CellInfoNrBuilder.newBuilder()
+ .setRegistered(REGISTERED)
+ .setTimeStampNanos(TIMESTAMP_NANOS)
+ .setCellConnectionStatus(CELL_CONNECTION_STATUS)
+ .setCellIdentity(cellIdentity)
+ .setCellSignalStrength(cellSignalStrength)
+ .build();
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/CellSignalStrengthNrBuilderTest.java b/robolectric/src/test/java/org/robolectric/shadows/CellSignalStrengthNrBuilderTest.java
new file mode 100644
index 000000000..1f18ee8dc
--- /dev/null
+++ b/robolectric/src/test/java/org/robolectric/shadows/CellSignalStrengthNrBuilderTest.java
@@ -0,0 +1,84 @@
+package org.robolectric.shadows;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Build;
+import android.telephony.CellInfo;
+import android.telephony.CellSignalStrengthNr;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+/** Test for {@link CellSignalStrengthNrBuilder} */
+@RunWith(AndroidJUnit4.class)
+@Config(minSdk = Build.VERSION_CODES.Q)
+public class CellSignalStrengthNrBuilderTest {
+
+ // The platform enforces that some of these values are within a certain range - otherwise, it will
+ // default to {@link android.telephony.CellInfo.UNAVAILABLE}.
+ private static final int CSI_RSRP = -100;
+ private static final int CSI_RSRQ = -10;
+ private static final int CSI_SINR = -20;
+ private static final int CSI_CQI_TABLE_INDEX = 1;
+ private static final ImmutableList<Byte> CSI_CQI_REPORT = ImmutableList.of((byte) 7);
+ private static final int SS_RSRP = -140;
+ private static final int SS_RSRQ = -15;
+ private static final int SS_SINR = -20;
+ private static final int TIMING_ADVANCE = 10;
+
+ @Test
+ public void build_noArguments() {
+ // The intent is to primarily verify that there are no issues setting default values i.e., no
+ // exceptions thrown or invalid inputs.
+ CellSignalStrengthNr cellSignalStrength = CellSignalStrengthNrBuilder.newBuilder().build();
+
+ assertThat(cellSignalStrength.getCsiRsrp()).isEqualTo(CellInfo.UNAVAILABLE);
+ }
+
+ @Test
+ @Config(minSdk = Build.VERSION_CODES.Q, maxSdk = Build.VERSION_CODES.S_V2)
+ public void build_sdkQtoS() {
+ CellSignalStrengthNr cellSignalStrength = getCellSignalStrength();
+
+ assertCellSignalStrengthFieldsForAllSdks(cellSignalStrength);
+ }
+
+ @Test
+ @Config(minSdk = Build.VERSION_CODES.TIRAMISU)
+ public void build_fromSdkT() {
+ CellSignalStrengthNr cellSignalStrength = getCellSignalStrength();
+
+ assertCellSignalStrengthFieldsForAllSdks(cellSignalStrength);
+ assertThat(cellSignalStrength.getCsiCqiTableIndex()).isEqualTo(CSI_CQI_TABLE_INDEX);
+ assertThat(cellSignalStrength.getCsiCqiReport()).containsExactly(7);
+ }
+
+ /**
+ * Assertions on {@link android.telephony.CellSignalStrengthNr} values that are common across all
+ * tested SDKs.
+ */
+ private void assertCellSignalStrengthFieldsForAllSdks(CellSignalStrengthNr cellSignalStrength) {
+ assertThat(cellSignalStrength.getCsiRsrp()).isEqualTo(CSI_RSRP);
+ assertThat(cellSignalStrength.getCsiRsrq()).isEqualTo(CSI_RSRQ);
+ assertThat(cellSignalStrength.getCsiSinr()).isEqualTo(CSI_SINR);
+ assertThat(cellSignalStrength.getSsRsrp()).isEqualTo(SS_RSRP);
+ assertThat(cellSignalStrength.getSsRsrq()).isEqualTo(SS_RSRQ);
+ assertThat(cellSignalStrength.getSsSinr()).isEqualTo(SS_SINR);
+ }
+
+ private CellSignalStrengthNr getCellSignalStrength() {
+ return CellSignalStrengthNrBuilder.newBuilder()
+ .setCsiRsrp(CSI_RSRP)
+ .setCsiRsrq(CSI_RSRQ)
+ .setCsiSinr(CSI_SINR)
+ .setCsiCqiTableIndex(CSI_CQI_TABLE_INDEX)
+ .setCsiCqiReport(CSI_CQI_REPORT)
+ .setSsRsrp(SS_RSRP)
+ .setSsRsrq(SS_RSRQ)
+ .setSsSinr(SS_SINR)
+ .setTimingAdvance(TIMING_ADVANCE)
+ .build();
+ }
+}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowAssetManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowAssetManagerTest.java
index 9ecb63d06..5de84d80d 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowAssetManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowAssetManagerTest.java
@@ -1,8 +1,8 @@
package org.robolectric.shadows;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.TruthJUnit.assume;
import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.robolectric.shadows.ShadowAssetManager.legacyShadowOf;
@@ -46,7 +46,7 @@ public class ShadowAssetManagerTest {
@Test
public void openFd_shouldProvideFileDescriptorForDeflatedAsset() throws Exception {
- assumeTrue(!useLegacy());
+ assume().that(useLegacy()).isFalse();
expectedException.expect(FileNotFoundException.class);
expectedException.expectMessage(
"This file can not be opened as a file descriptor; it is probably compressed");
@@ -79,7 +79,7 @@ public class ShadowAssetManagerTest {
@Test
public void openNonAssetShouldThrowExceptionWhenFileDoesNotExist() throws IOException {
- assumeTrue(useLegacy());
+ assume().that(useLegacy()).isTrue();
expectedException.expect(IOException.class);
expectedException.expectMessage(
@@ -90,7 +90,7 @@ public class ShadowAssetManagerTest {
@Test
public void unknownResourceIdsShouldReportPackagesSearched() throws IOException {
- assumeTrue(useLegacy());
+ assume().that(useLegacy()).isTrue();
expectedException.expect(Resources.NotFoundException.class);
expectedException.expectMessage("Resource ID #0xffffffff");
@@ -102,7 +102,7 @@ public class ShadowAssetManagerTest {
@Test
public void forSystemResources_unknownResourceIdsShouldReportPackagesSearched()
throws IOException {
- if (!useLegacy()) return;
+ assume().that(useLegacy()).isTrue();
expectedException.expect(Resources.NotFoundException.class);
expectedException.expectMessage("Resource ID #0xffffffff");
@@ -113,8 +113,7 @@ public class ShadowAssetManagerTest {
@Test
@Config(qualifiers = "mdpi")
public void openNonAssetShouldOpenCorrectAssetBasedOnQualifierMdpi() throws IOException {
- if (!useLegacy()) return;
-
+ assume().that(useLegacy()).isTrue();
InputStream inputStream = assetManager.openNonAsset(0, "res/drawable/robolectric.png", 0);
assertThat(countBytes(inputStream)).isEqualTo(8141);
}
@@ -122,8 +121,7 @@ public class ShadowAssetManagerTest {
@Test
@Config(qualifiers = "hdpi")
public void openNonAssetShouldOpenCorrectAssetBasedOnQualifierHdpi() throws IOException {
- if (!useLegacy()) return;
-
+ assume().that(useLegacy()).isTrue();
InputStream inputStream = assetManager.openNonAsset(0, "res/drawable/robolectric.png", 0);
assertThat(countBytes(inputStream)).isEqualTo(23447);
}
@@ -178,8 +176,7 @@ public class ShadowAssetManagerTest {
@Test
public void attrsToTypedArray_shouldAllowMockedAttributeSets() {
- if (!useLegacy()) return;
-
+ assume().that(useLegacy()).isTrue();
AttributeSet mockAttributeSet = mock(AttributeSet.class);
when(mockAttributeSet.getAttributeCount()).thenReturn(1);
when(mockAttributeSet.getAttributeNameResource(0)).thenReturn(android.R.attr.windowBackground);
@@ -191,7 +188,7 @@ public class ShadowAssetManagerTest {
@Test
public void whenStyleAttrResolutionFails_attrsToTypedArray_returnsNiceErrorMessage() {
- if (!useLegacy()) return;
+ assume().that(useLegacy()).isTrue();
expectedException.expect(RuntimeException.class);
expectedException.expectMessage(
"no value for org.robolectric:attr/styleNotSpecifiedInAnyTheme in theme with applied"
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowContextWrapperTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowContextWrapperTest.java
index 4d71cbfb4..03d9d732c 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowContextWrapperTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowContextWrapperTest.java
@@ -4,6 +4,7 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Build.VERSION_CODES.KITKAT;
import static android.os.Build.VERSION_CODES.M;
+import static android.os.Build.VERSION_CODES.P;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
@@ -46,6 +47,8 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ConfigTestReceiver;
+import org.robolectric.CustomConstructorReceiverWrapper.CustomConstructorWithEmptyActionReceiver;
+import org.robolectric.CustomConstructorReceiverWrapper.CustomConstructorWithOneActionReceiver;
import org.robolectric.R;
import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
@@ -95,6 +98,20 @@ public class ShadowContextWrapperTest {
}
@Test
+ @Config(manifest = "TestAndroidManifestWithAppComponentFactory.xml", minSdk = P)
+ public void registerReceiver_shouldGetReceiverWithCustomConstructorEmptyAction() {
+ BroadcastReceiver receiver = getReceiverOfClass(CustomConstructorWithEmptyActionReceiver.class);
+ assertThat(receiver).isInstanceOf(CustomConstructorWithEmptyActionReceiver.class);
+ }
+
+ @Test
+ @Config(manifest = "TestAndroidManifestWithAppComponentFactory.xml", minSdk = P)
+ public void registerReceiver_shouldGetReceiverWithCustomConstructorAndOneAction() {
+ BroadcastReceiver receiver = getReceiverOfClass(CustomConstructorWithOneActionReceiver.class);
+ assertThat(receiver).isInstanceOf(CustomConstructorWithOneActionReceiver.class);
+ }
+
+ @Test
public void registerReceiver_shouldRegisterForAllIntentFilterActions() throws Exception {
BroadcastReceiver receiver = broadcastReceiver("Larry");
contextWrapper.registerReceiver(receiver, intentFilter("foo", "baz"));
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowLauncherAppsTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowLauncherAppsTest.java
index 4b648f89e..47c16b4f4 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowLauncherAppsTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowLauncherAppsTest.java
@@ -198,6 +198,20 @@ public class ShadowLauncherAppsTest {
}
@Test
+ @Config(minSdk = L)
+ public void testIsActivityEnabled() {
+ ComponentName c1 = new ComponentName(ApplicationProvider.getApplicationContext(), "Activity1");
+ ComponentName c2 = new ComponentName(ApplicationProvider.getApplicationContext(), "Activity2");
+ ComponentName c3 = new ComponentName("other", "Activity1");
+ assertThat(launcherApps.isActivityEnabled(c1, USER_HANDLE)).isFalse();
+
+ shadowOf(launcherApps).setActivityEnabled(USER_HANDLE, c1);
+ assertThat(launcherApps.isActivityEnabled(c1, USER_HANDLE)).isTrue();
+ assertThat(launcherApps.isActivityEnabled(c2, USER_HANDLE)).isFalse();
+ assertThat(launcherApps.isActivityEnabled(c3, USER_HANDLE)).isFalse();
+ }
+
+ @Test
@Config(minSdk = O)
public void testGetApplicationInfo_packageNotFound() throws Exception {
Throwable throwable =
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPaintTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPaintTest.java
index 6ae57f951..7744b9507 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPaintTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPaintTest.java
@@ -71,6 +71,15 @@ public class ShadowPaintTest {
}
@Test
+ public void shouldSetStrikeThruText() {
+ Paint paint = new Paint();
+ paint.setStrikeThruText(true);
+ assertThat(paint.isStrikeThruText()).isTrue();
+ paint.setStrikeThruText(false);
+ assertThat(paint.isStrikeThruText()).isFalse();
+ }
+
+ @Test
public void measureTextActuallyMeasuresLength() {
Paint paint = new Paint();
assertThat(paint.measureText("Hello")).isEqualTo(5.0f);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowPausedLooperTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowPausedLooperTest.java
index 8801f1e1a..71e85c9b6 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowPausedLooperTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowPausedLooperTest.java
@@ -14,6 +14,7 @@ import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
+import android.os.Build.VERSION_CODES;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -33,6 +34,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
import org.robolectric.annotation.LooperMode;
import org.robolectric.res.android.Ref;
import org.robolectric.shadow.api.Shadow;
@@ -621,6 +623,43 @@ public class ShadowPausedLooperTest {
assertThat(foregroundThreadReceived.get()).isTrue();
}
+ @Test
+ @Config(minSdk = VERSION_CODES.M)
+ public void runOneTask_ignoreSyncBarrier() {
+ int barrier = Looper.getMainLooper().getQueue().postSyncBarrier();
+
+ final AtomicBoolean wasRun = new AtomicBoolean(false);
+ new Handler(Looper.getMainLooper()).post(() -> wasRun.set(true));
+
+ ShadowPausedLooper shadowPausedLooper = Shadow.extract(Looper.getMainLooper());
+ shadowPausedLooper.runOneTask();
+
+ // tasks should not be executed when blocked by a sync barrier
+ assertThat(wasRun.get()).isFalse();
+ // sync barrier will throw if the barrier was not found.
+ Looper.getMainLooper().getQueue().removeSyncBarrier(barrier);
+
+ shadowPausedLooper.runOneTask();
+ assertThat(wasRun.get()).isTrue();
+ }
+
+ @Test
+ @Config(minSdk = VERSION_CODES.P)
+ public void runOneTask_ignoreSyncBarrier_with_async() {
+ int barrier = Looper.getMainLooper().getQueue().postSyncBarrier();
+
+ final AtomicBoolean wasRun = new AtomicBoolean(false);
+ Handler.createAsync(Looper.getMainLooper()).post(() -> wasRun.set(true));
+
+ ShadowPausedLooper shadowPausedLooper = Shadow.extract(Looper.getMainLooper());
+ shadowPausedLooper.runOneTask();
+
+ // tasks should be executed as the handler is async
+ assertThat(wasRun.get()).isTrue();
+ // sync barrier will throw if the barrier was not found.
+ Looper.getMainLooper().getQueue().removeSyncBarrier(barrier);
+ }
+
private static class BlockingRunnable implements Runnable {
CountDownLatch latch = new CountDownLatch(1);
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowResourcesTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowResourcesTest.java
index da3440139..a4732b920 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowResourcesTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowResourcesTest.java
@@ -2,8 +2,7 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.N_MR1;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assume.assumeFalse;
-import static org.junit.Assume.assumeTrue;
+import static com.google.common.truth.TruthJUnit.assume;
import static org.robolectric.Shadows.shadowOf;
import static org.robolectric.shadows.ShadowAssetManager.useLegacy;
@@ -85,7 +84,7 @@ public class ShadowResourcesTest {
@Test
public void openRawResourceFd_shouldReturnsNullForLegacyResource() throws Exception {
- assumeTrue(useLegacy());
+ assume().that(useLegacy()).isTrue();
try (AssetFileDescriptor afd = resources.openRawResourceFd(R.raw.raw_resource)) {
assertThat(afd).isNull();
}
@@ -93,7 +92,7 @@ public class ShadowResourcesTest {
@Test
public void openRawResourceFd_shouldReturnsValidFdForUnCompressFile() throws Exception {
- assumeFalse(useLegacy());
+ assume().that(useLegacy()).isFalse();
try (AssetFileDescriptor afd = resources.openRawResourceFd(R.raw.raw_resource)) {
assertThat(afd).isNotNull();
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowSQLiteConnectionTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowSQLiteConnectionTest.java
index 323511fc3..878777c10 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowSQLiteConnectionTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowSQLiteConnectionTest.java
@@ -3,8 +3,8 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.common.truth.TruthJUnit.assume;
import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
import static org.robolectric.annotation.SQLiteMode.Mode.LEGACY;
import static org.robolectric.shadows.ShadowLegacySQLiteConnection.convertSQLWithLocalizedUnicodeCollator;
@@ -64,7 +64,7 @@ public class ShadowSQLiteConnectionTest {
@Test
public void testSqlConversion() {
- assumeTrue(SQLiteLibraryLoader.isOsSupported());
+ assume().that(SQLiteLibraryLoader.isOsSupported()).isTrue();
assertThat(convertSQLWithLocalizedUnicodeCollator("select * from `routine`"))
.isEqualTo("select * from `routine`");
@@ -88,7 +88,7 @@ public class ShadowSQLiteConnectionTest {
@Test
public void testSQLWithLocalizedOrUnicodeCollatorShouldBeSortedAsNoCase() {
- assumeTrue(SQLiteLibraryLoader.isOsSupported());
+ assume().that(SQLiteLibraryLoader.isOsSupported()).isTrue();
database.execSQL("insert into routine(name) values ('الصحافة اليدوية')");
database.execSQL("insert into routine(name) values ('Hand press 1')");
database.execSQL("insert into routine(name) values ('hand press 2')");
@@ -116,28 +116,28 @@ public class ShadowSQLiteConnectionTest {
@Test
public void nativeOpen_addsConnectionToPool() {
- assumeTrue(SQLiteLibraryLoader.isOsSupported());
+ assume().that(SQLiteLibraryLoader.isOsSupported()).isTrue();
assertThat(conn).isNotNull();
assertWithMessage("open").that(conn.isOpen()).isTrue();
}
@Test
public void nativeClose_closesConnection() {
- assumeTrue(SQLiteLibraryLoader.isOsSupported());
+ assume().that(SQLiteLibraryLoader.isOsSupported()).isTrue();
ShadowLegacySQLiteConnection.nativeClose(ptr);
assertWithMessage("open").that(conn.isOpen()).isFalse();
}
@Test
public void reset_closesConnection() {
- assumeTrue(SQLiteLibraryLoader.isOsSupported());
+ assume().that(SQLiteLibraryLoader.isOsSupported()).isTrue();
ShadowLegacySQLiteConnection.reset();
assertWithMessage("open").that(conn.isOpen()).isFalse();
}
@Test
public void reset_clearsConnectionCache() {
- assumeTrue(SQLiteLibraryLoader.isOsSupported());
+ assume().that(SQLiteLibraryLoader.isOsSupported()).isTrue();
final Map<Long, SQLiteConnection> connectionsMap =
ReflectionHelpers.getField(connections, "connectionsMap");
@@ -149,7 +149,7 @@ public class ShadowSQLiteConnectionTest {
@Test
public void reset_clearsStatementCache() {
- assumeTrue(SQLiteLibraryLoader.isOsSupported());
+ assume().that(SQLiteLibraryLoader.isOsSupported()).isTrue();
final Map<Long, SQLiteStatement> statementsMap =
ReflectionHelpers.getField(connections, "statementsMap");
@@ -161,7 +161,7 @@ public class ShadowSQLiteConnectionTest {
@Test
public void error_resultsInSpecificExceptionWithCause() {
- assumeTrue(SQLiteLibraryLoader.isOsSupported());
+ assume().that(SQLiteLibraryLoader.isOsSupported()).isTrue();
try {
database.execSQL("insert into routine(name) values ('Hand press 1')");
ContentValues values = new ContentValues(1);
@@ -178,7 +178,7 @@ public class ShadowSQLiteConnectionTest {
@Test
public void interruption_doesNotConcurrentlyModifyDatabase() {
- assumeTrue(SQLiteLibraryLoader.isOsSupported());
+ assume().that(SQLiteLibraryLoader.isOsSupported()).isTrue();
Thread.currentThread().interrupt();
try {
database.execSQL("insert into routine(name) values ('الصحافة اليدوية')");
@@ -190,7 +190,7 @@ public class ShadowSQLiteConnectionTest {
@Test
public void test_setUseInMemoryDatabase() {
- assumeTrue(SQLiteLibraryLoader.isOsSupported());
+ assume().that(SQLiteLibraryLoader.isOsSupported()).isTrue();
assertThat(conn.isMemoryDatabase()).isFalse();
ShadowSQLiteConnection.setUseInMemoryDatabase(true);
SQLiteDatabase inMemoryDb = createDatabase("in_memory.db");
@@ -201,7 +201,7 @@ public class ShadowSQLiteConnectionTest {
@Test
public void cancel_shouldCancelAllStatements() {
- assumeTrue(SQLiteLibraryLoader.isOsSupported());
+ assume().that(SQLiteLibraryLoader.isOsSupported()).isTrue();
SQLiteStatement statement1 =
database.compileStatement("insert into routine(name) values ('Hand press 1')");
SQLiteStatement statement2 =
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyManagerTest.java
index f6b09950d..ad3adebcf 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTelephonyManagerTest.java
@@ -27,6 +27,8 @@ import static android.telephony.TelephonyManager.CALL_STATE_OFFHOOK;
import static android.telephony.TelephonyManager.CALL_STATE_RINGING;
import static android.telephony.TelephonyManager.NETWORK_TYPE_EVDO_0;
import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE;
+import static android.telephony.emergency.EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE;
+import static android.telephony.emergency.EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static org.junit.Assert.assertEquals;
@@ -74,10 +76,12 @@ import android.telephony.TelephonyManager.BootstrapAuthenticationCallback;
import android.telephony.TelephonyManager.CellInfoCallback;
import android.telephony.UiccSlotInfo;
import android.telephony.VisualVoicemailSmsFilterSettings;
+import android.telephony.emergency.EmergencyNumber;
import android.telephony.gba.UaSecurityProtocolIdentifier;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
@@ -1101,4 +1105,36 @@ public class ShadowTelephonyManagerTest {
public void getEmergencyCallback_notSet_returnsFalse() {
assertThat(telephonyManager.getEmergencyCallbackMode()).isFalse();
}
+
+ @Test
+ @Config(minSdk = R)
+ public void getEmergencyNumbersList_notSet_returnsEmptyList() {
+ assertThat(telephonyManager.getEmergencyNumberList()).isEmpty();
+ }
+
+ @Test
+ @Config(minSdk = R)
+ public void getEmergencyNumbersList_wasSet_returnsCorrectList() throws Exception {
+ EmergencyNumber emergencyNumber =
+ EmergencyNumber.class
+ .getConstructor(
+ String.class,
+ String.class,
+ String.class,
+ int.class,
+ List.class,
+ int.class,
+ int.class)
+ .newInstance(
+ "911",
+ "us",
+ "30",
+ EMERGENCY_NUMBER_SOURCE_DATABASE,
+ ImmutableList.of(),
+ EMERGENCY_SERVICE_CATEGORY_POLICE,
+ EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+ ShadowTelephonyManager.setEmergencyNumberList(
+ ImmutableMap.of(0, ImmutableList.of(emergencyNumber)));
+ assertThat(telephonyManager.getEmergencyNumberList().get(0)).containsExactly(emergencyNumber);
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowVibratorTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowVibratorTest.java
index bc93daac0..ef5527abf 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowVibratorTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowVibratorTest.java
@@ -16,7 +16,6 @@ import android.content.Context;
import android.media.AudioAttributes;
import android.os.VibrationEffect;
import android.os.Vibrator;
-import android.os.vibrator.PrimitiveSegment;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
@@ -132,48 +131,6 @@ public class ShadowVibratorTest {
@Config(minSdk = S)
@Test
- public void getVibrationEffectSegments_composeOnce_shouldReturnSameFragment() {
- vibrator.vibrate(
- VibrationEffect.startComposition()
- .addPrimitive(EFFECT_CLICK, /* scale= */ 0.5f, /* delay= */ 20)
- .addPrimitive(EFFECT_CLICK, /* scale= */ 0.7f, /* delay= */ 50)
- .addPrimitive(EFFECT_CLICK, /* scale= */ 0.9f, /* delay= */ 150)
- .compose());
-
- assertThat(shadowOf(vibrator).getVibrationEffectSegments())
- .isEqualTo(
- ImmutableList.of(
- new PrimitiveSegment(EFFECT_CLICK, /* scale= */ 0.5f, /* delay= */ 20),
- new PrimitiveSegment(EFFECT_CLICK, /* scale= */ 0.7f, /* delay= */ 50),
- new PrimitiveSegment(EFFECT_CLICK, /* scale= */ 0.9f, /* delay= */ 150)));
- }
-
- @Config(minSdk = S)
- @Test
- public void getVibrationEffectSegments_composeTwice_shouldReturnTheLastComposition() {
- vibrator.vibrate(
- VibrationEffect.startComposition()
- .addPrimitive(EFFECT_CLICK, /* scale= */ 0.5f, /* delay= */ 20)
- .addPrimitive(EFFECT_CLICK, /* scale= */ 0.7f, /* delay= */ 50)
- .addPrimitive(EFFECT_CLICK, /* scale= */ 0.9f, /* delay= */ 150)
- .compose());
- vibrator.vibrate(
- VibrationEffect.startComposition()
- .addPrimitive(EFFECT_CLICK, /* scale= */ 0.4f, /* delay= */ 120)
- .addPrimitive(EFFECT_CLICK, /* scale= */ 0.9f, /* delay= */ 150)
- .addPrimitive(EFFECT_CLICK, /* scale= */ 1f, /* delay= */ 2150)
- .compose());
-
- assertThat(shadowOf(vibrator).getVibrationEffectSegments())
- .isEqualTo(
- ImmutableList.of(
- new PrimitiveSegment(EFFECT_CLICK, /* scale= */ 0.4f, /* delay= */ 120),
- new PrimitiveSegment(EFFECT_CLICK, /* scale= */ 0.9f, /* delay= */ 150),
- new PrimitiveSegment(EFFECT_CLICK, /* scale= */ 1f, /* delay= */ 2150)));
- }
-
- @Config(minSdk = S)
- @Test
public void getPrimitiveSegmentsInPrimitiveEffects_composeOnce_shouldReturnSameFragment() {
vibrator.vibrate(
VibrationEffect.startComposition()
diff --git a/robolectric/src/test/java/org/robolectric/util/SQLiteLibraryLoaderTest.java b/robolectric/src/test/java/org/robolectric/util/SQLiteLibraryLoaderTest.java
index 3b06a4e32..612fd3bfa 100644
--- a/robolectric/src/test/java/org/robolectric/util/SQLiteLibraryLoaderTest.java
+++ b/robolectric/src/test/java/org/robolectric/util/SQLiteLibraryLoaderTest.java
@@ -1,8 +1,8 @@
package org.robolectric.util;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.TruthJUnit.assume;
import static org.junit.Assert.assertThrows;
-import static org.junit.Assume.assumeTrue;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.After;
@@ -56,7 +56,7 @@ public class SQLiteLibraryLoaderTest {
@Test
public void shouldExtractNativeLibrary() {
- assumeTrue(SQLiteLibraryLoader.isOsSupported());
+ assume().that(SQLiteLibraryLoader.isOsSupported()).isTrue();
assertThat(loader.isLoaded()).isFalse();
loader.doLoad();
assertThat(loader.isLoaded()).isTrue();
diff --git a/robolectric/src/test/resources/TestAndroidManifestWithAppComponentFactory.xml b/robolectric/src/test/resources/TestAndroidManifestWithAppComponentFactory.xml
new file mode 100644
index 000000000..cbda17e65
--- /dev/null
+++ b/robolectric/src/test/resources/TestAndroidManifestWithAppComponentFactory.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">
+ <uses-sdk android:targetSdkVersion="18"/>
+
+ <application
+ android:appComponentFactory="org.robolectric.CustomAppComponentFactory">
+ <receiver
+ android:name=".CustomConstructorReceiverWrapper$CustomConstructorWithOneActionReceiver">
+ <intent-filter>
+ <action android:name="org.robolectric.ACTION_CUSTOM_CONSTRUCTOR"/>
+ </intent-filter>
+ </receiver>
+ <receiver
+ android:name=".CustomConstructorReceiverWrapper$CustomConstructorWithEmptyActionReceiver" />
+ </application>
+</manifest>
diff --git a/sandbox/build.gradle b/sandbox/build.gradle
index 64accd737..358b027c2 100644
--- a/sandbox/build.gradle
+++ b/sandbox/build.gradle
@@ -5,24 +5,24 @@ apply plugin: RoboJavaModulePlugin
apply plugin: DeployedRoboJavaModulePlugin
dependencies {
- annotationProcessor "com.google.auto.service:auto-service:$autoServiceVersion"
- annotationProcessor "com.google.errorprone:error_prone_core:$errorproneVersion"
+ annotationProcessor libs.auto.service
+ annotationProcessor libs.error.prone.core
api project(":annotations")
api project(":utils")
api project(":shadowapi")
api project(":utils:reflector")
- compileOnly "com.google.auto.service:auto-service-annotations:$autoServiceVersion"
- api "javax.annotation:javax.annotation-api:1.3.2"
- api "javax.inject:javax.inject:1"
+ compileOnly libs.auto.service.annotations
+ api libs.javax.annotation.api
+ api libs.javax.inject
- api "org.ow2.asm:asm:${asmVersion}"
- api "org.ow2.asm:asm-commons:${asmVersion}"
- api "com.google.guava:guava:$guavaJREVersion"
- compileOnly "com.google.code.findbugs:jsr305:3.0.2"
+ api libs.asm
+ api libs.asm.commons
+ api libs.guava
+ compileOnly libs.findbugs.jsr305
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation "org.mockito:mockito-core:${mockitoVersion}"
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.mockito
testImplementation project(":junit")
}
diff --git a/shadowapi/build.gradle b/shadowapi/build.gradle
index f63d048e1..3f0064fb7 100644
--- a/shadowapi/build.gradle
+++ b/shadowapi/build.gradle
@@ -5,11 +5,11 @@ apply plugin: RoboJavaModulePlugin
apply plugin: DeployedRoboJavaModulePlugin
dependencies {
- compileOnly "com.google.code.findbugs:jsr305:3.0.2"
+ compileOnly libs.findbugs.jsr305
api project(":annotations")
api project(":utils")
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation "org.mockito:mockito-core:${mockitoVersion}"
-} \ No newline at end of file
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.mockito
+}
diff --git a/shadowapi/src/main/java/org/robolectric/util/ReflectionHelpers.java b/shadowapi/src/main/java/org/robolectric/util/ReflectionHelpers.java
index eaaee1a3d..8ae639971 100644
--- a/shadowapi/src/main/java/org/robolectric/util/ReflectionHelpers.java
+++ b/shadowapi/src/main/java/org/robolectric/util/ReflectionHelpers.java
@@ -10,7 +10,6 @@ import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import javax.annotation.Nullable;
/** Collection of helper methods for calling methods and accessing fields reflectively. */
@SuppressWarnings(value = {"unchecked", "TypeParameterUnusedInFormals", "NewApi"})
@@ -45,9 +44,10 @@ public class ReflectionHelpers {
* <p>The returned object will be an instance of the given class, but all methods will return
* either the "default" value for primitives, or another deep proxy for non-primitive types.
*
- * <p>This should be used rarely, for cases where we need to create deep proxies in order not
- * to crash. The inner proxies are impossible to configure, so there is no way to create
- * meaningful behavior from a deep proxy. It serves mainly to prevent Null Pointer Exceptions.
+ * <p>This should be used rarely, for cases where we need to create deep proxies in order not to
+ * crash. The inner proxies are impossible to configure, so there is no way to create meaningful
+ * behavior from a deep proxy. It serves mainly to prevent Null Pointer Exceptions.
+ *
* @param clazz the class to provide a proxy instance of.
* @return a new "Deep Proxy" instance of the given class.
*/
@@ -127,7 +127,8 @@ public class ReflectionHelpers {
* @param fieldName The field name.
* @param fieldNewValue New value.
*/
- public static void setField(final Object object, final String fieldName, final Object fieldNewValue) {
+ public static void setField(
+ final Object object, final String fieldName, final Object fieldNewValue) {
try {
traverseClassHierarchy(
object.getClass(),
@@ -152,7 +153,8 @@ public class ReflectionHelpers {
* @param fieldName The field name.
* @param fieldNewValue New value.
*/
- public static void setField(Class<?> type, final Object object, final String fieldName, final Object fieldNewValue) {
+ public static void setField(
+ Class<?> type, final Object object, final String fieldName, final Object fieldNewValue) {
try {
Field field = type.getDeclaredField(fieldName);
field.setAccessible(true);
@@ -163,6 +165,22 @@ public class ReflectionHelpers {
}
/**
+ * Reflectively check if a class has a given field (static or non static).
+ *
+ * @param clazz Target class.
+ * @param fieldName The field name.
+ * @return boolean to indicate whether the field exists or not in clazz.
+ */
+ public static boolean hasField(Class<?> clazz, String fieldName) {
+ try {
+ Field field = clazz.getDeclaredField(fieldName);
+ return (field != null);
+ } catch (NoSuchFieldException e) {
+ return false;
+ }
+ }
+
+ /**
* Reflectively get the value of a static field.
*
* @param field Field object.
@@ -392,7 +410,9 @@ public class ReflectionHelpers {
public static <T> T newInstance(Class<T> cl) {
try {
return cl.getDeclaredConstructor().newInstance();
- } catch (InstantiationException | IllegalAccessException | NoSuchMethodException
+ } catch (InstantiationException
+ | IllegalAccessException
+ | NoSuchMethodException
| InvocationTargetException e) {
throw new RuntimeException(e);
}
@@ -465,15 +485,15 @@ public class ReflectionHelpers {
*/
public static class ClassParameter<V> {
public final Class<? extends V> clazz;
- public final V val;
+ public final V value;
- public ClassParameter(Class<? extends V> clazz, V val) {
+ public ClassParameter(Class<? extends V> clazz, V value) {
this.clazz = clazz;
- this.val = val;
+ this.value = value;
}
- public static <V> ClassParameter<V> from(Class<? extends V> clazz, V val) {
- return new ClassParameter<>(clazz, val);
+ public static <V> ClassParameter<V> from(Class<? extends V> clazz, V value) {
+ return new ClassParameter<>(clazz, value);
}
public static ClassParameter<?>[] fromComponentLists(Class<?>[] classes, Object[] values) {
@@ -496,7 +516,7 @@ public class ReflectionHelpers {
public static Object[] getValues(ClassParameter<?>... classParameters) {
Object[] values = new Object[classParameters.length];
for (int i = 0; i < classParameters.length; i++) {
- Object paramValue = classParameters[i].val;
+ Object paramValue = classParameters[i].value;
values[i] = paramValue;
}
return values;
@@ -510,15 +530,15 @@ public class ReflectionHelpers {
*/
public static class StringParameter<V> {
public final String className;
- public final V val;
+ public final V value;
- public StringParameter(String className, V val) {
+ public StringParameter(String className, V value) {
this.className = className;
- this.val = val;
+ this.value = value;
}
- public static <V> StringParameter<V> from(String className, V val) {
- return new StringParameter<>(className, val);
+ public static <V> StringParameter<V> from(String className, V value) {
+ return new StringParameter<>(className, value);
}
}
}
diff --git a/shadowapi/src/test/java/org/robolectric/util/ReflectionHelpersTest.java b/shadowapi/src/test/java/org/robolectric/util/ReflectionHelpersTest.java
index 56c489df1..e5f281ba6 100644
--- a/shadowapi/src/test/java/org/robolectric/util/ReflectionHelpersTest.java
+++ b/shadowapi/src/test/java/org/robolectric/util/ReflectionHelpersTest.java
@@ -141,7 +141,8 @@ public class ReflectionHelpersTest {
}
@Test
- public void callInstanceMethodReflectively_whenMultipleSignaturesExistForAMethodName_callsMethodWithCorrectSignature() {
+ public void
+ callInstanceMethodReflectively_whenMultipleSignaturesExistForAMethodName_callsMethodWithCorrectSignature() {
ExampleDescendant example = new ExampleDescendant();
int returnNumber =
ReflectionHelpers.callInstanceMethod(
@@ -282,23 +283,35 @@ public class ReflectionHelpersTest {
}
@Test
- public void callConstructorReflectively_whenMultipleSignaturesExistForTheConstructor_callsConstructorWithCorrectSignature() {
- ExampleClass ec = ReflectionHelpers.callConstructor(ExampleClass.class, ClassParameter.from(int.class, 16));
+ public void
+ callConstructorReflectively_whenMultipleSignaturesExistForTheConstructor_callsConstructorWithCorrectSignature() {
+ ExampleClass ec =
+ ReflectionHelpers.callConstructor(ExampleClass.class, ClassParameter.from(int.class, 16));
assertWithMessage("index").that(ec.index).isEqualTo(16);
assertWithMessage("name").that(ec.name).isNull();
}
- @SuppressWarnings("serial")
- private static class TestError extends Error {
+ @Test
+ public void callHasField_withstaticandregularmember() {
+ assertWithMessage("has field failed for member: unusedName")
+ .that(ReflectionHelpers.hasField(FieldTestClass.class, "unusedName"))
+ .isTrue();
+ assertWithMessage("has field failed for member: unusedStaticName")
+ .that(ReflectionHelpers.hasField(FieldTestClass.class, "unusedStaticName"))
+ .isTrue();
+ assertWithMessage("has field failed for non existant member: noname")
+ .that(ReflectionHelpers.hasField(FieldTestClass.class, "noname"))
+ .isFalse();
}
@SuppressWarnings("serial")
- private static class TestException extends Exception {
- }
+ private static class TestError extends Error {}
@SuppressWarnings("serial")
- private static class TestRuntimeException extends RuntimeException {
- }
+ private static class TestException extends Exception {}
+
+ @SuppressWarnings("serial")
+ private static class TestRuntimeException extends RuntimeException {}
@SuppressWarnings("unused")
private static class ExampleBase {
@@ -406,4 +419,11 @@ public class ReflectionHelpersTest {
this.index = index;
}
}
+
+ private static class FieldTestClass {
+ public String unusedName;
+ public static String unusedStaticName = "unusedStaticNameValue";
+
+ private FieldTestClass() {}
+ }
}
diff --git a/shadows/framework/build.gradle b/shadows/framework/build.gradle
index a273d5a6f..7c9aa5879 100644
--- a/shadows/framework/build.gradle
+++ b/shadows/framework/build.gradle
@@ -15,6 +15,8 @@ configurations {
sqlite4java
}
+def sqlite4javaVersion = libs.versions.sqlite4java.get()
+
task copySqliteNatives(type: Copy) {
from project.configurations.sqlite4java {
include '**/*.dll'
@@ -47,20 +49,17 @@ dependencies {
api project(":shadowapi")
api project(":utils")
api project(":utils:reflector")
+
api "androidx.test:monitor:$axtMonitorVersion@aar"
- implementation "com.google.errorprone:error_prone_annotations:$errorproneVersion"
- compileOnly "com.google.code.findbugs:jsr305:3.0.2"
- api "com.almworks.sqlite4java:sqlite4java:$sqlite4javaVersion"
- compileOnly(AndroidSdk.MAX_SDK.coordinates) { force = true }
- api "com.ibm.icu:icu4j:72.1"
- api "androidx.annotation:annotation:1.1.0"
- api "com.google.auto.value:auto-value-annotations:1.10.1"
- annotationProcessor "com.google.auto.value:auto-value:1.10.1"
+ implementation libs.error.prone.annotations
+ compileOnly libs.findbugs.jsr305
+ api libs.sqlite4java
+ compileOnly(AndroidSdk.MAX_SDK.coordinates)
+ api libs.icu4j
+ api libs.androidx.annotation
+ api libs.auto.value.annotations
+ annotationProcessor libs.auto.value
- sqlite4java "com.almworks.sqlite4java:libsqlite4java-osx:$sqlite4javaVersion"
- sqlite4java "com.almworks.sqlite4java:libsqlite4java-linux-amd64:$sqlite4javaVersion"
- sqlite4java "com.almworks.sqlite4java:sqlite4java-win32-x64:$sqlite4javaVersion"
- sqlite4java "com.almworks.sqlite4java:libsqlite4java-linux-i386:$sqlite4javaVersion"
- sqlite4java "com.almworks.sqlite4java:sqlite4java-win32-x86:$sqlite4javaVersion"
+ sqlite4java libs.bundles.sqlite4java.native
}
diff --git a/shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java b/shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java
index 0385636a8..0385636a8 100755..100644
--- a/shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java
+++ b/shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/AssociationInfoBuilder.java b/shadows/framework/src/main/java/org/robolectric/shadows/AssociationInfoBuilder.java
index 73c36a542..e2b8f0df3 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/AssociationInfoBuilder.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/AssociationInfoBuilder.java
@@ -80,19 +80,40 @@ public class AssociationInfoBuilder {
public AssociationInfo build() {
try {
if (RuntimeEnvironment.getApiLevel() <= TIRAMISU) {
- return ReflectionHelpers.callConstructor(
- AssociationInfo.class,
- ClassParameter.from(int.class, id),
- ClassParameter.from(int.class, userId),
- ClassParameter.from(String.class, packageName),
- ClassParameter.from(MacAddress.class, MacAddress.fromString(deviceMacAddress)),
- ClassParameter.from(CharSequence.class, displayName),
- ClassParameter.from(String.class, deviceProfile),
- ClassParameter.from(boolean.class, selfManaged),
- ClassParameter.from(boolean.class, notifyOnDeviceNearby),
- ClassParameter.from(boolean.class, false /*revoked*/),
- ClassParameter.from(long.class, approvedMs),
- ClassParameter.from(long.class, lastTimeConnectedMs));
+ // We have two different constructors for AssociationInfo across
+ // T branches. aosp has the constructor that takes a new "revoked" parameter.
+ // Since there is not deterministic way to know which branch we are running in,
+ // we will reflect on the class to see if it has the mRevoked member.
+ // Based on the result we will either invoke the constructor with "revoked" or the
+ // one without this parameter.
+ if (ReflectionHelpers.hasField(AssociationInfo.class, "mRevoked")) {
+ return ReflectionHelpers.callConstructor(
+ AssociationInfo.class,
+ ClassParameter.from(int.class, id),
+ ClassParameter.from(int.class, userId),
+ ClassParameter.from(String.class, packageName),
+ ClassParameter.from(MacAddress.class, MacAddress.fromString(deviceMacAddress)),
+ ClassParameter.from(CharSequence.class, displayName),
+ ClassParameter.from(String.class, deviceProfile),
+ ClassParameter.from(boolean.class, selfManaged),
+ ClassParameter.from(boolean.class, notifyOnDeviceNearby),
+ ClassParameter.from(boolean.class, false /*revoked only supported in aosp*/),
+ ClassParameter.from(long.class, approvedMs),
+ ClassParameter.from(long.class, lastTimeConnectedMs));
+ } else {
+ return ReflectionHelpers.callConstructor(
+ AssociationInfo.class,
+ ClassParameter.from(int.class, id),
+ ClassParameter.from(int.class, userId),
+ ClassParameter.from(String.class, packageName),
+ ClassParameter.from(MacAddress.class, MacAddress.fromString(deviceMacAddress)),
+ ClassParameter.from(CharSequence.class, displayName),
+ ClassParameter.from(String.class, deviceProfile),
+ ClassParameter.from(boolean.class, selfManaged),
+ ClassParameter.from(boolean.class, notifyOnDeviceNearby),
+ ClassParameter.from(long.class, approvedMs),
+ ClassParameter.from(long.class, lastTimeConnectedMs));
+ }
} else {
return ReflectionHelpers.callConstructor(
AssociationInfo.class,
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/CellIdentityNrBuilder.java b/shadows/framework/src/main/java/org/robolectric/shadows/CellIdentityNrBuilder.java
new file mode 100644
index 000000000..22a0e75c0
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/CellIdentityNrBuilder.java
@@ -0,0 +1,135 @@
+package org.robolectric.shadows;
+
+import static org.robolectric.util.reflector.Reflector.reflector;
+
+import android.os.Build;
+import android.telephony.CellIdentityNr;
+import android.telephony.CellInfo;
+import androidx.annotation.RequiresApi;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.reflector.Constructor;
+import org.robolectric.util.reflector.ForType;
+
+/** Builder for {@link android.telephony.CellIdentityNr}. */
+@RequiresApi(Build.VERSION_CODES.Q)
+public class CellIdentityNrBuilder {
+
+ private int pci = CellInfo.UNAVAILABLE;
+ private int tac = CellInfo.UNAVAILABLE;
+ private int nrarfcn = CellInfo.UNAVAILABLE;
+ private int[] bands = new int[0];
+ @Nullable private String mcc = null;
+ @Nullable private String mnc = null;
+ private long nci = CellInfo.UNAVAILABLE;
+ @Nullable private String alphal = null;
+ @Nullable private String alphas = null;
+ private List<String> additionalPlmns = new ArrayList<>();
+
+ private CellIdentityNrBuilder() {}
+
+ public static CellIdentityNrBuilder newBuilder() {
+ return new CellIdentityNrBuilder();
+ }
+
+ // An empty constructor is not available on Q.
+ @RequiresApi(Build.VERSION_CODES.R)
+ protected static CellIdentityNr getDefaultInstance() {
+ return reflector(CellIdentityNrReflector.class).newCellIdentityNr();
+ }
+
+ public CellIdentityNrBuilder setNci(long nci) {
+ this.nci = nci;
+ return this;
+ }
+
+ public CellIdentityNrBuilder setPci(int pci) {
+ this.pci = pci;
+ return this;
+ }
+
+ public CellIdentityNrBuilder setTac(int tac) {
+ this.tac = tac;
+ return this;
+ }
+
+ public CellIdentityNrBuilder setNrarfcn(int nrarfcn) {
+ this.nrarfcn = nrarfcn;
+ return this;
+ }
+
+ public CellIdentityNrBuilder setMcc(String mcc) {
+ this.mcc = mcc;
+ return this;
+ }
+
+ public CellIdentityNrBuilder setMnc(String mnc) {
+ this.mnc = mnc;
+ return this;
+ }
+
+ public CellIdentityNrBuilder setBands(int[] bands) {
+ this.bands = bands;
+ return this;
+ }
+
+ public CellIdentityNrBuilder setLongOperatorName(String longOperatorName) {
+ this.alphal = longOperatorName;
+ return this;
+ }
+
+ public CellIdentityNrBuilder setShortOperatorName(String shortOperatorName) {
+ this.alphas = shortOperatorName;
+ return this;
+ }
+
+ public CellIdentityNrBuilder setAdditionalPlmns(List<String> additionalPlmns) {
+ this.additionalPlmns = additionalPlmns;
+ return this;
+ }
+
+ public CellIdentityNr build() {
+ CellIdentityNrReflector cellIdentityReflector = reflector(CellIdentityNrReflector.class);
+ if (RuntimeEnvironment.getApiLevel() < Build.VERSION_CODES.R) {
+ return cellIdentityReflector.newCellIdentityNr(
+ pci, tac, nrarfcn, mcc, mnc, nci, alphal, alphas);
+ } else {
+ return cellIdentityReflector.newCellIdentityNr(
+ pci, tac, nrarfcn, bands, mcc, mnc, nci, alphal, alphas, additionalPlmns);
+ }
+ }
+
+ @ForType(CellIdentityNr.class)
+ private interface CellIdentityNrReflector {
+
+ @Constructor
+ CellIdentityNr newCellIdentityNr();
+
+ @Constructor
+ CellIdentityNr newCellIdentityNr(
+ int pci,
+ int tac,
+ int nrarfcn,
+ String mcc,
+ String mnc,
+ long nci,
+ String alphal,
+ String alphas);
+
+ @Constructor
+ CellIdentityNr newCellIdentityNr(
+ int pci,
+ int tac,
+ int nrarfcn,
+ int[] bands,
+ String mcc,
+ String mnc,
+ long nci,
+ String alphal,
+ String alphas,
+ Collection<String> additionalPlmns);
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/CellInfoLteBuilder.java b/shadows/framework/src/main/java/org/robolectric/shadows/CellInfoLteBuilder.java
index 412d8c72f..6f3f93420 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/CellInfoLteBuilder.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/CellInfoLteBuilder.java
@@ -57,13 +57,17 @@ public class CellInfoLteBuilder {
}
public CellInfoLte build() {
+ int apiLevel = RuntimeEnvironment.getApiLevel();
if (cellIdentity == null) {
- cellIdentity = CellIdentityLteBuilder.getDefaultInstance();
+ if (apiLevel > Build.VERSION_CODES.Q) {
+ cellIdentity = CellIdentityLteBuilder.getDefaultInstance();
+ } else {
+ cellIdentity = CellIdentityLteBuilder.newBuilder().build();
+ }
}
if (cellSignalStrength == null) {
cellSignalStrength = CellSignalStrengthLteBuilder.getDefaultInstance();
}
- int apiLevel = RuntimeEnvironment.getApiLevel();
CellInfoLteReflector cellInfoLteReflector = reflector(CellInfoLteReflector.class);
if (apiLevel < Build.VERSION_CODES.TIRAMISU) {
CellInfoLte cellInfo = cellInfoLteReflector.newCellInfoLte();
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/CellInfoNrBuilder.java b/shadows/framework/src/main/java/org/robolectric/shadows/CellInfoNrBuilder.java
new file mode 100644
index 000000000..78195246e
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/CellInfoNrBuilder.java
@@ -0,0 +1,93 @@
+package org.robolectric.shadows;
+
+import static org.robolectric.util.reflector.Reflector.reflector;
+
+import android.os.Build;
+import android.os.Parcel;
+import android.telephony.CellIdentityNr;
+import android.telephony.CellInfoNr;
+import android.telephony.CellSignalStrengthNr;
+import androidx.annotation.RequiresApi;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.reflector.Constructor;
+import org.robolectric.util.reflector.ForType;
+
+/** Builder for {@link android.telephony.CellInfoNr}. */
+@RequiresApi(Build.VERSION_CODES.Q)
+public class CellInfoNrBuilder {
+
+ private boolean isRegistered = false;
+ private long timeStamp = 0L;
+ private int cellConnectionStatus = 0;
+ private CellIdentityNr cellIdentity;
+ private CellSignalStrengthNr cellSignalStrength;
+
+ private CellInfoNrBuilder() {}
+
+ public static CellInfoNrBuilder newBuilder() {
+ return new CellInfoNrBuilder();
+ }
+
+ public CellInfoNrBuilder setRegistered(boolean isRegistered) {
+ this.isRegistered = isRegistered;
+ return this;
+ }
+
+ public CellInfoNrBuilder setTimeStampNanos(long timeStamp) {
+ this.timeStamp = timeStamp;
+ return this;
+ }
+
+ public CellInfoNrBuilder setCellConnectionStatus(int cellConnectionStatus) {
+ this.cellConnectionStatus = cellConnectionStatus;
+ return this;
+ }
+
+ public CellInfoNrBuilder setCellIdentity(CellIdentityNr cellIdentity) {
+ this.cellIdentity = cellIdentity;
+ return this;
+ }
+
+ public CellInfoNrBuilder setCellSignalStrength(CellSignalStrengthNr cellSignalStrength) {
+ this.cellSignalStrength = cellSignalStrength;
+ return this;
+ }
+
+ public CellInfoNr build() {
+ if (cellIdentity == null) {
+ cellIdentity = CellIdentityNrBuilder.getDefaultInstance();
+ }
+ if (cellSignalStrength == null) {
+ cellSignalStrength = CellSignalStrengthNrBuilder.getDefaultInstance();
+ }
+ // CellInfoNr has no default constructor below T so we write it to a Parcel.
+ if (RuntimeEnvironment.getApiLevel() <= Build.VERSION_CODES.TIRAMISU) {
+ Parcel p = Parcel.obtain();
+ p.writeInt(/* CellInfo#TYPE_NR */ 6);
+ p.writeInt(isRegistered ? 1 : 0);
+ p.writeLong(timeStamp);
+ p.writeInt(cellConnectionStatus);
+ cellIdentity.writeToParcel(p, 0);
+ cellSignalStrength.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ CellInfoNr cellInfoNr = CellInfoNr.CREATOR.createFromParcel(p);
+ p.recycle();
+ return cellInfoNr;
+ } else {
+ return reflector(CellInfoNrReflector.class)
+ .newCellInfoNr(
+ cellConnectionStatus, isRegistered, timeStamp, cellIdentity, cellSignalStrength);
+ }
+ }
+
+ @ForType(CellInfoNr.class)
+ private interface CellInfoNrReflector {
+ @Constructor
+ CellInfoNr newCellInfoNr(
+ int cellConnectionStatus,
+ boolean isRegistered,
+ long timeStamp,
+ CellIdentityNr cellIdentity,
+ CellSignalStrengthNr cellSignalStrength);
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/CellSignalStrengthNrBuilder.java b/shadows/framework/src/main/java/org/robolectric/shadows/CellSignalStrengthNrBuilder.java
new file mode 100644
index 000000000..4f3f859bc
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/CellSignalStrengthNrBuilder.java
@@ -0,0 +1,140 @@
+package org.robolectric.shadows;
+
+import static org.robolectric.util.reflector.Reflector.reflector;
+
+import android.os.Build;
+import android.telephony.CellInfo;
+import android.telephony.CellSignalStrengthNr;
+import androidx.annotation.RequiresApi;
+import java.util.ArrayList;
+import java.util.List;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.reflector.Constructor;
+import org.robolectric.util.reflector.ForType;
+
+/** Builder for {@link android.telephony.CellSignalStrengthNr} */
+@RequiresApi(Build.VERSION_CODES.Q)
+public class CellSignalStrengthNrBuilder {
+
+ private int csiRrsp = CellInfo.UNAVAILABLE;
+ private int csiRsrq = CellInfo.UNAVAILABLE;
+ private int csiSinr = CellInfo.UNAVAILABLE;
+ private int csiCqiTableIndex = CellInfo.UNAVAILABLE;
+ private List<Byte> csiCqiReport = new ArrayList<>();
+ private int ssRsrp = CellInfo.UNAVAILABLE;
+ private int ssRsrq = CellInfo.UNAVAILABLE;
+ private int ssSinr = CellInfo.UNAVAILABLE;
+ private int timingAdvance = CellInfo.UNAVAILABLE;
+
+ private CellSignalStrengthNrBuilder() {}
+
+ public static CellSignalStrengthNrBuilder newBuilder() {
+ return new CellSignalStrengthNrBuilder();
+ }
+
+ protected static CellSignalStrengthNr getDefaultInstance() {
+ return reflector(CellSignalStrengthNrReflector.class).newCellSignalStrengthNr();
+ }
+
+ public CellSignalStrengthNrBuilder setCsiRsrp(int csiRrsp) {
+ this.csiRrsp = csiRrsp;
+ return this;
+ }
+
+ public CellSignalStrengthNrBuilder setCsiRsrq(int csiRsrq) {
+ this.csiRsrq = csiRsrq;
+ return this;
+ }
+
+ public CellSignalStrengthNrBuilder setCsiSinr(int csiSinr) {
+ this.csiSinr = csiSinr;
+ return this;
+ }
+
+ public CellSignalStrengthNrBuilder setCsiCqiTableIndex(int csiCqiTableIndex) {
+ this.csiCqiTableIndex = csiCqiTableIndex;
+ return this;
+ }
+
+ public CellSignalStrengthNrBuilder setCsiCqiReport(List<Byte> csiCqiReport) {
+ this.csiCqiReport = csiCqiReport;
+ return this;
+ }
+
+ public CellSignalStrengthNrBuilder setSsRsrp(int ssRsrp) {
+ this.ssRsrp = ssRsrp;
+ return this;
+ }
+
+ public CellSignalStrengthNrBuilder setSsRsrq(int ssRsrq) {
+ this.ssRsrq = ssRsrq;
+ return this;
+ }
+
+ public CellSignalStrengthNrBuilder setSsSinr(int ssSinr) {
+ this.ssSinr = ssSinr;
+ return this;
+ }
+
+ public CellSignalStrengthNrBuilder setTimingAdvance(int timingAdvance) {
+ this.timingAdvance = timingAdvance;
+ return this;
+ }
+
+ public CellSignalStrengthNr build() {
+ CellSignalStrengthNrReflector cellSignalStrengthReflector =
+ reflector(CellSignalStrengthNrReflector.class);
+ if (RuntimeEnvironment.getApiLevel() < Build.VERSION_CODES.TIRAMISU) {
+ return cellSignalStrengthReflector.newCellSignalStrengthNr(
+ csiRrsp, csiRsrq, csiSinr, ssRsrp, ssRsrq, ssSinr);
+ } else if (RuntimeEnvironment.getApiLevel() == Build.VERSION_CODES.TIRAMISU) {
+ return cellSignalStrengthReflector.newCellSignalStrengthNr(
+ csiRrsp, csiRsrq, csiSinr, csiCqiTableIndex, csiCqiReport, ssRsrp, ssRsrq, ssSinr);
+ } else {
+ return cellSignalStrengthReflector.newCellSignalStrengthNr(
+ csiRrsp,
+ csiRsrq,
+ csiSinr,
+ csiCqiTableIndex,
+ csiCqiReport,
+ ssRsrp,
+ ssRsrq,
+ ssSinr,
+ timingAdvance);
+ }
+ }
+
+ @ForType(CellSignalStrengthNr.class)
+ private interface CellSignalStrengthNrReflector {
+
+ @Constructor
+ CellSignalStrengthNr newCellSignalStrengthNr();
+
+ @Constructor
+ CellSignalStrengthNr newCellSignalStrengthNr(
+ int csRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr);
+
+ @Constructor
+ CellSignalStrengthNr newCellSignalStrengthNr(
+ int csRsrp,
+ int csiRsrq,
+ int csiSinr,
+ int csiCqiTableIndex,
+ List<Byte> csiCqiReport,
+ int ssRsrp,
+ int ssRsrq,
+ int ssSinr);
+
+ @Constructor
+ CellSignalStrengthNr newCellSignalStrengthNr(
+ int csRsrp,
+ int csiRsrq,
+ int csiSinr,
+ int csiCqiTableIndex,
+ List<Byte> csiCqiReport,
+ int ssRsrp,
+ int ssRsrq,
+ int ssSinr,
+ int timingAdvance);
+ }
+}
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 eb2276c9e..eb2276c9e 100755..100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscApkAssets9.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscApkAssets9.java
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 c0c9c7a8e..c0c9c7a8e 100755..100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscAssetManager.java
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayManagerGlobal.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayManagerGlobal.java
index 3ae8895ae..d0fdab014 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayManagerGlobal.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayManagerGlobal.java
@@ -18,16 +18,12 @@ import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayInfo;
import com.google.common.annotations.VisibleForTesting;
-
import java.lang.reflect.Field;
-import java.sql.Array;
-import java.text.Format;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.annotation.Nullable;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.Bootstrap;
import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
@@ -84,18 +80,31 @@ public class ShadowDisplayManagerGlobal {
private static DisplayManagerGlobal newDisplayManagerGlobal(IDisplayManager displayManager) {
instance = Shadow.newInstanceOf(DisplayManagerGlobal.class);
DisplayManagerGlobalReflector displayManagerGlobal =
- reflector(DisplayManagerGlobalReflector.class, instance);
+ reflector(DisplayManagerGlobalReflector.class, instance);
displayManagerGlobal.setDm(displayManager);
displayManagerGlobal.setLock(new Object());
- List<Handler> displayListeners =
- RuntimeEnvironment.getApiLevel() < ShadowBuild.UPSIDE_DOWN_CAKE
- ? new ArrayList<>()
- : new CopyOnWriteArrayList<>();
+ List<Handler> displayListeners = createDisplayListeners();
displayManagerGlobal.setDisplayListeners(displayListeners);
displayManagerGlobal.setDisplayInfoCache(new SparseArray<>());
return instance;
}
+ private static List<Handler> createDisplayListeners() {
+ try {
+ // The type for mDisplayListeners was changed from ArrayList to CopyOnWriteArrayList
+ // in some branches of T and U, so we need to reflect on DisplayManagerGlobal class
+ // to check the type of mDisplayListeners member before initializing appropriately.
+ Field f = DisplayManagerGlobal.class.getDeclaredField("mDisplayListeners");
+ if (f.getType().isAssignableFrom(ArrayList.class)) {
+ return new ArrayList<>();
+ } else {
+ return new CopyOnWriteArrayList<>();
+ }
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
@VisibleForTesting
static DisplayManagerGlobal getGlobalInstance() {
return instance;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLauncherApps.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLauncherApps.java
index 96cd2c29b..0cbc9fb21 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLauncherApps.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLauncherApps.java
@@ -49,6 +49,7 @@ import org.robolectric.util.reflector.ForType;
public class ShadowLauncherApps {
private List<ShortcutInfo> shortcuts = new ArrayList<>();
private final Multimap<UserHandle, String> enabledPackages = HashMultimap.create();
+ private final Multimap<UserHandle, ComponentName> enabledActivities = HashMultimap.create();
private final Multimap<UserHandle, LauncherActivityInfo> shortcutActivityList =
HashMultimap.create();
private final Multimap<UserHandle, LauncherActivityInfo> activityList = HashMultimap.create();
@@ -102,6 +103,17 @@ public class ShadowLauncherApps {
}
/**
+ * Sets an activity referenced by ComponentName as enabled, to be checked by {@link
+ * #isActivityEnabled(ComponentName, UserHandle)}.
+ *
+ * @param userHandle the user handle to be set.
+ * @param componentName the component name of the activity to be enabled.
+ */
+ public void setActivityEnabled(UserHandle userHandle, ComponentName componentName) {
+ enabledActivities.put(userHandle, componentName);
+ }
+
+ /**
* Adds a {@link LauncherActivityInfo} to be retrieved by {@link
* #getShortcutConfigActivityList(String, UserHandle)}.
*
@@ -246,10 +258,9 @@ public class ShadowLauncherApps {
"This method is not currently supported in Robolectric.");
}
- @Implementation
+ @Implementation(minSdk = L)
protected boolean isActivityEnabled(ComponentName component, UserHandle user) {
- throw new UnsupportedOperationException(
- "This method is not currently supported in Robolectric.");
+ return enabledActivities.containsEntry(user, component);
}
/**
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLoadedApk.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLoadedApk.java
index 2a3a61b10..f954ac234 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLoadedApk.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowLoadedApk.java
@@ -1,20 +1,38 @@
package org.robolectric.shadows;
+import static org.robolectric.shadow.api.Shadow.newInstanceOf;
+import static org.robolectric.util.reflector.Reflector.reflector;
+
import android.app.Application;
import android.app.LoadedApk;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.os.Build.VERSION_CODES;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
import org.robolectric.util.reflector.Accessor;
import org.robolectric.util.reflector.ForType;
@Implements(value = LoadedApk.class, isInAndroidSdk = false)
public class ShadowLoadedApk {
+ @RealObject private LoadedApk realLoadedApk;
+ private boolean isClassLoaderInitialized = false;
+ private final Object classLoaderLock = new Object();
@Implementation
public ClassLoader getClassLoader() {
+ // The AppComponentFactory was introduced from SDK 28.
+ if (RuntimeEnvironment.getApiLevel() >= VERSION_CODES.P) {
+ synchronized (classLoaderLock) {
+ if (!isClassLoaderInitialized) {
+ isClassLoaderInitialized = true;
+ tryInitAppComponentFactory(realLoadedApk);
+ }
+ }
+ }
return this.getClass().getClassLoader();
}
@@ -23,6 +41,35 @@ public class ShadowLoadedApk {
return this.getClass().getClassLoader();
}
+ private void tryInitAppComponentFactory(LoadedApk realLoadedApk) {
+ if (RuntimeEnvironment.getApiLevel() >= VERSION_CODES.P) {
+ ApplicationInfo applicationInfo = realLoadedApk.getApplicationInfo();
+ if (applicationInfo == null || applicationInfo.appComponentFactory == null) {
+ return;
+ }
+ _LoadedApk_ loadedApkReflector = reflector(_LoadedApk_.class, realLoadedApk);
+ if (!loadedApkReflector.getIncludeCode()) {
+ return;
+ }
+ String fullQualifiedClassName =
+ calculateFullQualifiedClassName(
+ applicationInfo.appComponentFactory, applicationInfo.packageName);
+ android.app.AppComponentFactory factory =
+ (android.app.AppComponentFactory) newInstanceOf(fullQualifiedClassName);
+ if (factory == null) {
+ factory = new android.app.AppComponentFactory();
+ }
+ loadedApkReflector.setAppFactory(factory);
+ }
+ }
+
+ private String calculateFullQualifiedClassName(String className, String packageName) {
+ if (packageName == null) {
+ return className;
+ }
+ return className.startsWith(".") ? packageName + className : className;
+ }
+
/** Accessor interface for {@link LoadedApk}'s internals. */
@ForType(LoadedApk.class)
public interface _LoadedApk_ {
@@ -32,5 +79,11 @@ public class ShadowLoadedApk {
@Accessor("mResources")
void setResources(Resources resources);
+
+ @Accessor("mIncludeCode")
+ boolean getIncludeCode();
+
+ @Accessor("mAppComponentFactory")
+ void setAppFactory(Object appFactory);
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeFontsFontFamily.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeFontsFontFamily.java
index af3725cb6..b2da82783 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeFontsFontFamily.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeFontsFontFamily.java
@@ -3,7 +3,6 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.Q;
import static android.os.Build.VERSION_CODES.S;
import static android.os.Build.VERSION_CODES.TIRAMISU;
-import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
import android.graphics.fonts.FontFamily;
import org.robolectric.annotation.Implementation;
@@ -58,7 +57,7 @@ public class ShadowNativeFontsFontFamily {
FontFamilyBuilderNatives.nAddFont(builderPtr, fontPtr);
}
- @Implementation(maxSdk=TIRAMISU)
+ @Implementation(maxSdk = TIRAMISU)
protected static long nBuild(
long builderPtr, String langTags, int variant, boolean isCustomFallback) {
return FontFamilyBuilderNatives.nBuild(builderPtr, langTags, variant, isCustomFallback);
@@ -66,8 +65,12 @@ public class ShadowNativeFontsFontFamily {
@Implementation(minSdk = ShadowBuild.UPSIDE_DOWN_CAKE)
protected static long nBuild(
- long builderPtr, String langTags, int variant, boolean isCustomFallback, boolean isDefaultFallback) {
- return nBuild(builderPtr, langTags, variant, isCustomFallback);
+ long builderPtr,
+ String langTags,
+ int variant,
+ boolean isCustomFallback,
+ boolean isDefaultFallback) {
+ return FontFamilyBuilderNatives.nBuild(builderPtr, langTags, variant, isCustomFallback);
}
@Implementation
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 8fec6464a..16a7398f7 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java
@@ -112,6 +112,15 @@ public class ShadowPaint {
}
@Implementation
+ protected void setStrikeThruText(boolean strikeThruText) {
+ if (strikeThruText) {
+ setFlags(flags | Paint.STRIKE_THRU_TEXT_FLAG);
+ } else {
+ setFlags(flags & ~Paint.STRIKE_THRU_TEXT_FLAG);
+ }
+ }
+
+ @Implementation
protected Shader setShader(Shader shader) {
this.shader = shader;
return shader;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPausedMessageQueue.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPausedMessageQueue.java
index 416033b9b..5caf01642 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPausedMessageQueue.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPausedMessageQueue.java
@@ -59,7 +59,16 @@ public class ShadowPausedMessageQueue extends ShadowMessageQueue {
invokeConstructor(MessageQueue.class, realQueue, from(boolean.class, quitAllowed));
int ptr = (int) nativeQueueRegistry.register(this);
reflector(MessageQueueReflector.class, realQueue).setPtr(ptr);
- clockListener = () -> nativeWake(ptr);
+ clockListener =
+ () -> {
+ synchronized (realQueue) {
+ // only wake up the Looper thread if queue is non empty to reduce contention if many
+ // Looper threads are active
+ if (getMessages() != null) {
+ nativeWake(ptr);
+ }
+ }
+ };
ShadowPausedSystemClock.addStaticListener(clockListener);
}
@@ -307,7 +316,9 @@ public class ShadowPausedMessageQueue extends ShadowMessageQueue {
return Duration.ZERO;
}
while (next != null) {
- when = shadowOfMsg(next).getWhen();
+ if (next.getTarget() != null) {
+ when = shadowOfMsg(next).getWhen();
+ }
next = shadowOfMsg(next).internalGetNext();
}
}
@@ -333,7 +344,9 @@ public class ShadowPausedMessageQueue extends ShadowMessageQueue {
synchronized (realQueue) {
Message next = getMessages();
while (next != null) {
- count++;
+ if (next.getTarget() != null) {
+ count++;
+ }
next = shadowOfMsg(next).internalGetNext();
}
}
@@ -347,12 +360,24 @@ public class ShadowPausedMessageQueue extends ShadowMessageQueue {
*/
Message getNextIgnoringWhen() {
synchronized (realQueue) {
- Message head = getMessages();
- if (head != null) {
- Message next = shadowOfMsg(head).internalGetNext();
- reflector(MessageQueueReflector.class, realQueue).setMessages(next);
+ Message prev = null;
+ Message msg = getMessages();
+ // Head is blocked on synchronization barrier, find next asynchronous message.
+ if (msg != null && msg.getTarget() == null) {
+ do {
+ prev = msg;
+ msg = shadowOfMsg(msg).internalGetNext();
+ } while (msg != null && !msg.isAsynchronous());
+ }
+ if (msg != null) {
+ Message next = shadowOfMsg(msg).internalGetNext();
+ if (prev == null) {
+ reflector(MessageQueueReflector.class, realQueue).setMessages(next);
+ } else {
+ ReflectionHelpers.setField(prev, "next", next);
+ }
}
- return head;
+ return msg;
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemVibrator.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemVibrator.java
index cce1990a0..41fbf4e7d 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemVibrator.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemVibrator.java
@@ -15,9 +15,9 @@ import android.media.AudioAttributes;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemVibrator;
-import android.os.VibrationAttributes;
import android.os.VibrationEffect;
import android.os.vibrator.VibrationEffectSegment;
+import com.google.common.base.Preconditions;
import java.util.List;
import java.util.Optional;
import org.robolectric.RuntimeEnvironment;
@@ -25,7 +25,8 @@ import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.util.ReflectionHelpers;
-@Implements(value = SystemVibrator.class, isInAndroidSdk = false)
+/** Shadow for {@link SystemVibrator}. */
+@Implements(value = SystemVibrator.class, isInAndroidSdk = false, looseSignatures = true)
public class ShadowSystemVibrator extends ShadowVibrator {
private final Handler handler = new Handler(Looper.getMainLooper());
@@ -133,11 +134,14 @@ public class ShadowSystemVibrator extends ShadowVibrator {
@Implementation(minSdk = S)
protected void vibrate(
- int uid,
- String opPkg,
- VibrationEffect effect,
- String reason,
- VibrationAttributes attributes) {
+ Object uid, Object opPkg, Object effect, Object reason, Object attributes) {
+ Preconditions.checkArgument(uid instanceof Integer);
+ Preconditions.checkArgument(opPkg == null || opPkg instanceof String);
+ // The SystemVibrator#vibrate needs effect NonNull.
+ Preconditions.checkArgument(effect instanceof VibrationEffect);
+ Preconditions.checkArgument(reason == null || reason instanceof String);
+ // The SystemVibrator#vibrate needs attributes NonNull.
+ Preconditions.checkArgument(attributes instanceof android.os.VibrationAttributes);
if (effect instanceof VibrationEffect.Composed) {
VibrationEffect.Composed composedEffect = (VibrationEffect.Composed) effect;
vibrationAttributesFromLastVibration = attributes;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephonyManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephonyManager.java
index 0ab373054..048abf03b 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephonyManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephonyManager.java
@@ -52,6 +52,7 @@ import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager.CellInfoCallback;
import android.telephony.VisualVoicemailSmsFilterSettings;
+import android.telephony.emergency.EmergencyNumber;
import android.text.TextUtils;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -59,6 +60,7 @@ import com.google.common.base.Ascii;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Collections;
@@ -155,6 +157,7 @@ public class ShadowTelephonyManager {
private VisualVoicemailSmsParams lastVisualVoicemailSmsParams;
private VisualVoicemailSmsFilterSettings visualVoicemailSmsFilterSettings;
private boolean emergencyCallbackMode;
+ private static Map<Integer, List<EmergencyNumber>> emergencyNumbersList;
/**
* Should be {@link TelephonyManager.BootstrapAuthenticationCallback} but this object was
@@ -172,6 +175,7 @@ public class ShadowTelephonyManager {
@Resetter
public static void reset() {
callComposerStatus = 0;
+ emergencyNumbersList = null;
}
@Implementation(minSdk = S)
@@ -1411,4 +1415,25 @@ public class ShadowTelephonyManager {
return sentIntent;
}
}
+
+ /**
+ * Sets the emergency numbers list returned by {@link TelephonyManager#getEmergencyNumberList}.
+ */
+ public static void setEmergencyNumberList(
+ Map<Integer, List<EmergencyNumber>> emergencyNumbersList) {
+ ShadowTelephonyManager.emergencyNumbersList = emergencyNumbersList;
+ }
+
+ /**
+ * Implementation for {@link TelephonyManager#getEmergencyNumberList}.
+ *
+ * @return an immutable map by default, unless set with {@link #setEmergencyNumberList}.
+ */
+ @Implementation(minSdk = R)
+ protected Map<Integer, List<EmergencyNumber>> getEmergencyNumberList() {
+ if (ShadowTelephonyManager.emergencyNumbersList != null) {
+ return ShadowTelephonyManager.emergencyNumbersList;
+ }
+ return ImmutableMap.of();
+ }
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVibrator.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVibrator.java
index df299c795..276a31db3 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVibrator.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVibrator.java
@@ -3,11 +3,9 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.R;
import android.media.AudioAttributes;
-import android.os.VibrationAttributes;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.os.vibrator.PrimitiveSegment;
-import android.os.vibrator.VibrationEffectSegment;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -25,10 +23,10 @@ public class ShadowVibrator {
static boolean cancelled;
static long milliseconds;
protected static long[] pattern;
- protected static final List<VibrationEffectSegment> vibrationEffectSegments = new ArrayList<>();
+ protected static final List<Object> vibrationEffectSegments = new ArrayList<>();
protected static final List<PrimitiveEffect> primitiveEffects = new ArrayList<>();
protected static final List<Integer> supportedPrimitives = new ArrayList<>();
- @Nullable protected static VibrationAttributes vibrationAttributesFromLastVibration;
+ @Nullable protected static Object vibrationAttributesFromLastVibration;
@Nullable protected static AudioAttributes audioAttributesFromLastVibration;
static int repeat;
static boolean hasVibrator = true;
@@ -84,11 +82,6 @@ public class ShadowVibrator {
return repeat;
}
- /** Returns the last list of {@link VibrationEffectSegment}. */
- public List<VibrationEffectSegment> getVibrationEffectSegments() {
- return vibrationEffectSegments;
- }
-
/** Returns the last list of {@link PrimitiveSegment} vibrations in {@link PrimitiveEffect}. */
@SuppressWarnings("JdkCollectors") // toImmutableList is only supported in Java 8+.
public List<PrimitiveEffect> getPrimitiveSegmentsInPrimitiveEffects() {
@@ -125,9 +118,9 @@ public class ShadowVibrator {
supportedPrimitives.addAll(primitives);
}
- /** Returns the {@link VibrationAttributes} from the last vibration. */
+ /** Returns the {@link android.os.VibrationAttributes} from the last vibration. */
@Nullable
- public VibrationAttributes getVibrationAttributesFromLastVibration() {
+ public Object getVibrationAttributesFromLastVibration() {
return vibrationAttributesFromLastVibration;
}
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 706d86e10..1a8131f01 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebView.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWebView.java
@@ -569,7 +569,7 @@ public class ShadowWebView extends ShadowViewGroup {
*
* @param canGoBack Value to return from {@code android.webkit.WebView#canGoBack()}
* @deprecated Do not depend on this method as it will be removed in a future update. The
- * preferered method is to populate a fake web history to use for going back.
+ * preferred method is to populate a fake web history to use for going back.
*/
@Deprecated
public void setCanGoBack(boolean canGoBack) {
diff --git a/shadows/httpclient/build.gradle b/shadows/httpclient/build.gradle
index 332c83e08..4e77a09c3 100644
--- a/shadows/httpclient/build.gradle
+++ b/shadows/httpclient/build.gradle
@@ -21,17 +21,17 @@ dependencies {
api project(":utils")
// We should keep httpclient version for low level API compatibility.
- earlyRuntime "org.apache.httpcomponents:httpcore:4.0.1"
- api "org.apache.httpcomponents:httpclient:4.0.3"
- compileOnly(AndroidSdk.LOLLIPOP_MR1.coordinates) { force = true }
+ earlyRuntime libs.apache.http.core
+ api libs.apache.http.client
+ compileOnly(AndroidSdk.LOLLIPOP_MR1.coordinates)
testImplementation project(":robolectric")
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation "org.mockito:mockito-core:${mockitoVersion}"
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.mockito
testImplementation "androidx.test.ext:junit:$axtJunitVersion@aar"
- testCompileOnly(AndroidSdk.LOLLIPOP_MR1.coordinates) { force = true }
+ testCompileOnly(AndroidSdk.LOLLIPOP_MR1.coordinates)
testRuntimeOnly AndroidSdk.S.coordinates
}
diff --git a/shadows/playservices/build.gradle b/shadows/playservices/build.gradle
index c3abbba05..b00983893 100644
--- a/shadows/playservices/build.gradle
+++ b/shadows/playservices/build.gradle
@@ -14,25 +14,20 @@ shadows {
dependencies {
compileOnly project(":shadows:framework")
api project(":annotations")
- api "com.google.guava:guava:$guavaJREVersion"
+ api libs.guava
- compileOnly "androidx.fragment:fragment:1.2.0"
- compileOnly "com.google.android.gms:play-services-base:8.4.0"
- compileOnly "com.google.android.gms:play-services-basement:8.4.0"
+ compileOnly libs.bundles.play.services.base.for.shadows
compileOnly AndroidSdk.MAX_SDK.coordinates
testCompileOnly AndroidSdk.MAX_SDK.coordinates
- testCompileOnly "com.google.android.gms:play-services-base:8.4.0"
- testCompileOnly "com.google.android.gms:play-services-basement:8.4.0"
+ testCompileOnly libs.bundles.play.services.base.for.shadows
testImplementation project(":robolectric")
- testImplementation "junit:junit:$junitVersion"
- testImplementation "com.google.truth:truth:$truthVersion"
- testImplementation "org.mockito:mockito-core:$mockitoVersion"
- testRuntimeOnly "androidx.fragment:fragment:1.2.0"
- testRuntimeOnly "com.google.android.gms:play-services-base:8.4.0"
- testRuntimeOnly "com.google.android.gms:play-services-basement:8.4.0"
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.mockito
+ testRuntimeOnly libs.bundles.play.services.base.for.shadows
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
}
diff --git a/testapp/build.gradle b/testapp/build.gradle
index 651ced0ea..0abf895ae 100644
--- a/testapp/build.gradle
+++ b/testapp/build.gradle
@@ -2,6 +2,7 @@ apply plugin: 'com.android.library'
android {
compileSdk 33
+ namespace 'org.robolectric.testapp'
defaultConfig {
minSdk 16
diff --git a/utils/build.gradle b/utils/build.gradle
index c10cca279..c31c9a0e0 100644
--- a/utils/build.gradle
+++ b/utils/build.gradle
@@ -1,3 +1,4 @@
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.robolectric.gradle.DeployedRoboJavaModulePlugin
import org.robolectric.gradle.RoboJavaModulePlugin
@@ -13,7 +14,7 @@ spotless {
}
}
-tasks.withType(GenerateModuleMetadata) {
+tasks.withType(GenerateModuleMetadata).configureEach {
// We don't want to release gradle module metadata now to avoid
// potential compatibility problems.
enabled = false
@@ -26,7 +27,7 @@ compileKotlin {
// in production. If utils module starts to add Kotlin code in main source
// set, we can remove this destinationDirectory modification.
destinationDirectory = file("${projectDir}/build/classes/java/main")
- compilerOptions.jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8
+ compilerOptions.jvmTarget = JvmTarget.JVM_1_8
}
afterEvaluate {
@@ -48,20 +49,19 @@ afterEvaluate {
dependencies {
api project(":annotations")
api project(":pluginapi")
- api "javax.inject:javax.inject:1"
- api "javax.annotation:javax.annotation-api:1.3.2"
+ api libs.javax.inject
+ api libs.javax.annotation.api
// For @VisibleForTesting and ByteStreams
- implementation "com.google.guava:guava:$guavaJREVersion"
- compileOnly "com.google.code.findbugs:jsr305:3.0.2"
+ implementation libs.guava
+ compileOnly libs.findbugs.jsr305
- testCompileOnly "com.google.auto.service:auto-service-annotations:$autoServiceVersion"
- testAnnotationProcessor "com.google.auto.service:auto-service:$autoServiceVersion"
- testAnnotationProcessor "com.google.errorprone:error_prone_core:$errorproneVersion"
- implementation "com.google.errorprone:error_prone_annotations:$errorproneVersion"
+ testCompileOnly libs.auto.service.annotations
+ testAnnotationProcessor libs.auto.service
+ testAnnotationProcessor libs.error.prone.core
+ implementation libs.error.prone.annotations
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
- testImplementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
- testImplementation "org.mockito:mockito-core:${mockitoVersion}"
+ testImplementation libs.junit4
+ testImplementation libs.truth
+ testImplementation libs.kotlin.stdlib
}
diff --git a/utils/reflector/build.gradle b/utils/reflector/build.gradle
index 302734505..140e98700 100644
--- a/utils/reflector/build.gradle
+++ b/utils/reflector/build.gradle
@@ -5,12 +5,12 @@ apply plugin: RoboJavaModulePlugin
apply plugin: DeployedRoboJavaModulePlugin
dependencies {
- api "org.ow2.asm:asm:${asmVersion}"
- api "org.ow2.asm:asm-commons:${asmVersion}"
- api "org.ow2.asm:asm-util:${asmVersion}"
+ api libs.asm
+ api libs.asm.commons
+ api libs.asm.util
api project(":utils")
testImplementation project(":shadowapi")
- testImplementation "junit:junit:${junitVersion}"
- testImplementation "com.google.truth:truth:${truthVersion}"
+ testImplementation libs.junit4
+ testImplementation libs.truth
}
diff --git a/utils/src/main/java/org/robolectric/util/Util.java b/utils/src/main/java/org/robolectric/util/Util.java
index b7292ad93..b7292ad93 100755..100644
--- a/utils/src/main/java/org/robolectric/util/Util.java
+++ b/utils/src/main/java/org/robolectric/util/Util.java