aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-03 00:46:24 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-02-03 00:46:24 +0000
commitca926c544a956134055a195c680cacb83f6439c6 (patch)
treed7e4c349115c02703eb550a1c3f17d1a876b8791
parent19e60fd1e79394e05bff86b46f007d6c36827e1f (diff)
parentf4cf3e68fe97e5ec87afd811eb8e2b1bd4d57234 (diff)
downloadrobolectric-ca926c544a956134055a195c680cacb83f6439c6.tar.gz
Merge "Snap for 11400057 from e5340a5031ab402cc91a47d89af3f833dd960ba7 to simpleperf-release" into simpleperf-release
-rw-r--r--Android.bp57
-rw-r--r--README.md6
-rw-r--r--annotations/Android.bp2
-rw-r--r--integration_tests/nativegraphics/Android.bp8
-rw-r--r--integration_tests/nativegraphics/lint-baseline.xml37
-rw-r--r--nativeruntime/Android.bp2
-rw-r--r--resources/src/main/java/org/robolectric/manifest/AndroidManifest.java10
-rw-r--r--robolectric/Android.bp5
-rw-r--r--robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java70
-rw-r--r--robolectric/src/main/java/org/robolectric/android/internal/AndroidTestEnvironment.java1
-rw-r--r--robolectric/src/main/java/org/robolectric/internal/ResourcesMode.java3
-rw-r--r--robolectric/src/test/java/org/robolectric/RobolectricTestRunnerTest.java18
-rw-r--r--robolectric/src/test/java/org/robolectric/SingleSdkRobolectricTestRunner.java5
-rw-r--r--robolectric/src/test/java/org/robolectric/manifest/AndroidManifestTest.java13
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothAdapterTest.java36
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowMediaActionSoundTest.java19
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowStorageManagerTest.java12
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowTelecomManagerTest.java15
-rw-r--r--robolectric/src/test/java/org/robolectric/shadows/ShadowVirtualDeviceManagerTest.java14
-rw-r--r--sandbox/src/main/java/org/robolectric/config/AndroidConfigurer.java4
-rw-r--r--shadows/framework/Android.bp12
-rw-r--r--shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java13
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBinder.java8
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java39
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowHidlSupport.java16
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowKeyCharacterMap.java20
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaActionSound.java14
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeHardwareRenderer.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativePaint.java44
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java43
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java2
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java21
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowStorageManager.java4
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelecomManager.java6
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/ShadowVirtualDeviceManager.java10
-rw-r--r--shadows/framework/src/main/java/org/robolectric/shadows/WifiUsabilityStatsEntryBuilder.java1
-rw-r--r--shadows/httpclient/Android.bp4
-rw-r--r--shadows/multidex/Android.bp2
-rw-r--r--shadows/playservices/Android.bp2
-rw-r--r--shadows/versioning/Android.bp2
-rw-r--r--soong/Android.bp32
-rw-r--r--soong/robolectric.go101
-rw-r--r--testapp/Android.bp8
-rw-r--r--testapp/lint-baseline.xml26
44 files changed, 538 insertions, 233 deletions
diff --git a/Android.bp b/Android.bp
index 0a83bf58a..3c278f580 100644
--- a/Android.bp
+++ b/Android.bp
@@ -51,33 +51,31 @@ license {
],
}
-// Empty library. Should be removed
-java_library {
- name: "robolectric_android-all-stub_upstream",
- visibility: ["//visibility:public"],
-}
-
// build.prop file created by module type defined in soong/robolectric.go
robolectric_build_props {
- name: "robolectric_build_props_upstream",
+ name: "robolectric_build_props",
+ visibility: [
+ ":__subpackages__",
+ "//external/robolectric-shadows:__subpackages__",
+ ],
}
java_genrule {
- name: "robolectric_framework_res_upstream",
+ name: "robolectric_framework_res",
host_supported: true,
tools: ["zip2zip"],
srcs: [":framework-res"],
- out: ["robolectric_framework_res_upstream.jar"],
+ out: ["robolectric_framework_res.jar"],
cmd: "$(location zip2zip) " +
"-i $(location :framework-res) " +
- "-o $(location robolectric_framework_res_upstream.jar) " +
+ "-o $(location robolectric_framework_res.jar) " +
"-x classes.dex " +
"-x META-INF/**/* " +
"-0 resources.arsc",
}
java_device_for_host {
- name: "robolectric_android-all-device-deps_upstream",
+ name: "robolectric_android-all-device-deps",
libs: [
"conscrypt-for-host",
"core-icu4j-for-host",
@@ -93,39 +91,38 @@ java_device_for_host {
"services.accessibility",
"telephony-common",
"android.car",
- "androidx.test.monitor",
- "androidx.test.ext.truth", // -nodep?
+ "android.car.builtin",
],
}
java_library_host {
- name: "robolectric-host-android_all_upstream",
+ name: "robolectric-host-android_all",
static_libs: [
- "robolectric_android-all-device-deps_upstream",
+ "robolectric_android-all-device-deps",
"robolectric_tzdata",
- "robolectric_framework_res_upstream",
+ "robolectric_framework_res",
],
dist: {
targets: [
"sdk",
"win_sdk",
],
- dest: "android-all-robolectric_upstream.jar",
+ dest: "android-all-robolectric.jar",
},
java_resources: [
// Copy the build.prop
- ":robolectric_build_props_upstream",
+ ":robolectric_build_props",
],
visibility: [
":__subpackages__",
+ "//external/robolectric-shadows:__subpackages__",
"//prebuilts/misc/common/robolectric",
"//test/robolectric-extensions:__subpackages__",
"//frameworks/base/packages/SettingsLib/tests/robotests:__subpackages__",
],
}
-
java_library_host {
name: "Robolectric_all_upstream",
@@ -173,15 +170,21 @@ java_host_for_device {
//java references
"//frameworks/opt/net/wifi/libs/WifiTrackerLib/tests:__pkg__",
"//prebuilts/sdk/current/androidx:__pkg__",
+ "//prebuilts/sdk/current/androidx/m2repository/androidx/car/app/app-testing/1.4.0-alpha01:__pkg__",
"//prebuilts/sdk/current/aaos-libs:__pkg__",
"//packages/apps/TV/tests/common:__pkg__",
+ "//external/android_onboarding/src/com/android/onboarding/contracts/testing:__pkg__",
+ "//external/android_onboarding/src/com/android/onboarding/testing:__pkg__",
+ "//external/android_onboarding/src/com/android/onboarding/nodes/testing:__pkg__",
//robolectric tests
"//platform_testing/libraries/runner:__pkg__",
+ "//platform_testing/libraries/screenshot/material_components:__pkg__",
"//vendor:__subpackages__",
"//platform_testing/robolab/roboStandaloneProj/tests:__pkg__",
"//external/mobile-data-download/javatests:__pkg__",
"//frameworks/base/services/robotests:__pkg__",
"//frameworks/base/services/robotests/backup:__pkg__",
+ "//frameworks/base/packages/CredentialManager:__subpackages__",
"//frameworks/base/packages/SettingsLib/tests/robotests:__subpackages__",
"//frameworks/base/packages/SettingsLib/Spa/screenshot:__subpackages__",
"//frameworks/base/packages/SystemUI:__pkg__",
@@ -195,6 +198,7 @@ java_host_for_device {
"//packages/modules/Connectivity/nearby/tests/multidevices/clients/test_support/snippet_helper/tests:__pkg__",
"//packages/modules/Connectivity/nearby/tests/robotests:__pkg__",
"//packages/modules/DeviceLock/DeviceLockController/tests/robolectric:__pkg__",
+ "//packages/modules/DeviceLock/tests/unittests:__pkg__",
"//packages/services/Car/tests/CarLibTests:__pkg__",
"//packages/services/Mms/tests/robotests:__pkg__",
"//packages/apps/QuickAccessWallet/tests/robolectric:__pkg__",
@@ -202,6 +206,7 @@ java_host_for_device {
"//packages/apps/Car/libs/car-media-common/tests/robotests",
"//packages/apps/Car/libs/car-ui-lib",
"//packages/apps/Car/Notification/tests/robotests:__pkg__",
+ "//packages/apps/Car/Launcher/libs/appgrid/lib/robotests:__pkg__",
"//packages/apps/Car/Cluster/DirectRenderingCluster/tests/robotests:__pkg__",
"//packages/apps/Car/Settings/tests/robotests:__pkg__",
"//packages/apps/EmergencyInfo/tests/robolectric:__pkg__",
@@ -212,9 +217,13 @@ java_host_for_device {
"//packages/apps/TvSettings/Settings/tests/robotests:__pkg__",
"//packages/apps/KeyChain/robotests:__pkg__",
"//packages/apps/CertInstaller/robotests:__pkg__",
+ "//packages/providers/MediaProvider:__subpackages__",
+ "//packages/apps/TV:__subpackages__",
+ "//frameworks/base/libs/WindowManager/Shell:__subpackages__",
//tm-dev additions
"//frameworks/base/packages/BackupEncryption/test/robolectric-integration:__pkg__",
"//frameworks/base/packages/BackupEncryption/test/robolectric:__pkg__",
+ "//packages/apps/Settings/tests/screenshot:__pkg__",
],
}
@@ -235,6 +244,11 @@ java_device_for_host {
}
java_device_for_host {
+ name: "robolectric-host-androidx-test-ext-truth_upstream",
+ libs: ["androidx.test.ext.truth"],
+}
+
+java_device_for_host {
name: "robolectric-host-androidx-test-runner_upstream",
libs: ["androidx.test.runner"],
}
@@ -249,11 +263,6 @@ java_device_for_host {
libs: ["androidx.test.espresso.idling-resource"],
}
-//java_device_for_host {
-// name: "robolectric-host-android-support-v4_upstream",
-// libs: ["android-support-v4"],
-//}
-
java_device_for_host {
name: "robolectric-host-android-support-multidex_upstream",
libs: [
diff --git a/README.md b/README.md
index d8df03df6..0fe4d4471 100644
--- a/README.md
+++ b/README.md
@@ -49,12 +49,6 @@ Robolectric is built using Gradle. Both IntelliJ and Android Studio can import t
### Prerequisites
-Those software configurations are recommended and tested.
-
-- JDK 17. Gradle JVM should be set to Java 17.
- - For command line, make sure the environment variable `JAVA_HOME` is correctly point to JDK17, or set the build environment by [Gradle CLI option](https://docs.gradle.org/current/userguide/command_line_interface.html#sec:environment_options) `-Dorg.gradle.java.home="YourJdkHomePath"` or by [Gradle Properties](https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties) `org.gradle.java.home=YourJdkHomePath`.
- - For both IntelliJ and Android Studio, see _Settings/Preferences | Build, Execution, Deployment | Build Tools | Gradle_.
-
See [Building Robolectric](http://robolectric.org/building-robolectric/) for more details about setting up a build environment for Robolectric.
### Building
diff --git a/annotations/Android.bp b/annotations/Android.bp
index b325236d0..fd17be03c 100644
--- a/annotations/Android.bp
+++ b/annotations/Android.bp
@@ -16,7 +16,7 @@ java_library_host {
static_libs: [
"jsr305",
],
- libs: ["robolectric-host-android_all_upstream"],
+ libs: ["robolectric-host-android_all"],
srcs: ["src/main/java/**/*.java"],
visibility: ["//visibility:public"],
}
diff --git a/integration_tests/nativegraphics/Android.bp b/integration_tests/nativegraphics/Android.bp
index 43040dc2d..b5a7ffe20 100644
--- a/integration_tests/nativegraphics/Android.bp
+++ b/integration_tests/nativegraphics/Android.bp
@@ -11,7 +11,10 @@ android_library {
platform_apis: true,
manifest: "AndroidManifest.xml",
optimize: {
- enabled: false
+ enabled: false,
+ },
+ lint: {
+ baseline_filename: "lint-baseline.xml",
},
}
@@ -35,6 +38,9 @@ android_app {
kotlincflags: ["-Xjvm-default=all"],
plugins: ["dagger2-compiler"],
+ lint: {
+ baseline_filename: "lint-baseline.xml",
+ },
}
android_robolectric_test {
diff --git a/integration_tests/nativegraphics/lint-baseline.xml b/integration_tests/nativegraphics/lint-baseline.xml
new file mode 100644
index 000000000..7fb99b50d
--- /dev/null
+++ b/integration_tests/nativegraphics/lint-baseline.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01">
+
+ <issue
+ id="NewApi"
+ message="`android:forceDarkAllowed` requires API level 29 (current min is 26)"
+ errorLine1=' &lt;item name="android:forceDarkAllowed"&gt;false&lt;/item&gt;'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="external/robolectric/integration_tests/nativegraphics/src/main/res/values/themes.xml"
+ line="28"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`android:forceDarkAllowed` requires API level 29 (current min is 26)"
+ errorLine1=' &lt;item name="android:forceDarkAllowed"&gt;true&lt;/item&gt;'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="external/robolectric/integration_tests/nativegraphics/src/main/res/values/themes.xml"
+ line="31"
+ column="15"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`android:isLightTheme` requires API level 29 (current min is 26)"
+ errorLine1=' &lt;item name="android:isLightTheme"&gt;true&lt;/item&gt;'
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="external/robolectric/integration_tests/nativegraphics/src/main/res/values/themes.xml"
+ line="32"
+ column="15"/>
+ </issue>
+
+</issues> \ No newline at end of file
diff --git a/nativeruntime/Android.bp b/nativeruntime/Android.bp
index 262b29db4..2110f4abc 100644
--- a/nativeruntime/Android.bp
+++ b/nativeruntime/Android.bp
@@ -32,7 +32,7 @@ java_library_host {
"error_prone_annotations",
"auto_service_annotations",
// "jsr330",
- "robolectric-host-android_all_upstream",
+ "robolectric-host-android_all",
],
static_libs: [
"robolectric_nativeruntime_native_prebuilt",
diff --git a/resources/src/main/java/org/robolectric/manifest/AndroidManifest.java b/resources/src/main/java/org/robolectric/manifest/AndroidManifest.java
index 49127977d..00a11f5ff 100644
--- a/resources/src/main/java/org/robolectric/manifest/AndroidManifest.java
+++ b/resources/src/main/java/org/robolectric/manifest/AndroidManifest.java
@@ -218,8 +218,7 @@ public class AndroidManifest implements UsesSdk {
String targetSdkText =
getTagAttributeText(manifestDocument, "uses-sdk", "android:targetSdkVersion");
if (targetSdkText != null) {
- // Support Android O Preview. This can be removed once Android O is officially launched.
- targetSdkVersion = targetSdkText.equals("O") ? 26 : Integer.parseInt(targetSdkText);
+ targetSdkVersion = Integer.parseInt(targetSdkText);
}
maxSdkVersion =
@@ -240,6 +239,9 @@ public class AndroidManifest implements UsesSdk {
System.out.println("Falling back to the Android OS resources only.");
System.out.println(
"To remove this warning, annotate your test class with @Config(manifest=Config.NONE).");
+ System.out.println(
+ "If you're using Android Gradle Plugin, add "
+ + "testOptions.unitTests.includeAndroidResources = true to your build.gradle");
}
if (packageName == null || packageName.equals("")) {
@@ -247,10 +249,6 @@ public class AndroidManifest implements UsesSdk {
}
rClassName = packageName + ".R";
-
- if (androidManifestFile != null) {
- System.err.println("No such manifest file: " + androidManifestFile);
- }
}
manifestIsParsed = true;
diff --git a/robolectric/Android.bp b/robolectric/Android.bp
index dde56624f..b6720e96f 100644
--- a/robolectric/Android.bp
+++ b/robolectric/Android.bp
@@ -37,7 +37,7 @@ java_library_host {
"jsr305",
"conscrypt-unbundled",
"robolectric-host-androidx_test_espresso",
- "robolectric-host-android_all_upstream",
+ "robolectric-host-android_all",
],
srcs: ["src/main/java/**/*.java"],
plugins: ["auto_service_plugin"],
@@ -92,8 +92,9 @@ java_test_host {
"asm-9.2",
"jsr305",
"robolectric-host-androidx_test_espresso",
+ "robolectric-host-androidx-test-ext-truth_upstream",
],
- libs: ["robolectric-host-android_all_upstream"],
+ libs: ["robolectric-host-android_all"],
// Robolectric tests do not work well with unit tests setup yet
test_options: {
unit_test: false,
diff --git a/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java b/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
index 4cac1665f..def624b88 100644
--- a/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
+++ b/robolectric/src/main/java/org/robolectric/RobolectricTestRunner.java
@@ -1,6 +1,5 @@
package org.robolectric;
-import android.os.Build;
import com.google.auto.service.AutoService;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
@@ -89,7 +88,6 @@ public class RobolectricTestRunner extends SandboxTestRunner {
private final ConfigurationStrategy configurationStrategy;
private final AndroidConfigurer androidConfigurer;
- private final ResModeStrategy resModeStrategy = getResModeStrategy();
private boolean alwaysIncludeVariantMarkersInName =
Boolean.parseBoolean(
System.getProperty("robolectric.alwaysIncludeVariantMarkersInTestName", "false"));
@@ -185,31 +183,6 @@ public class RobolectricTestRunner extends SandboxTestRunner {
return DefaultTestLifecycle.class;
}
- enum ResModeStrategy {
- legacy,
- binary,
- best,
- both;
-
- static final ResModeStrategy DEFAULT = best;
-
- private static ResModeStrategy getFromProperties() {
- String resourcesMode = System.getProperty("robolectric.resourcesMode");
- return resourcesMode == null ? DEFAULT : valueOf(resourcesMode);
- }
-
- boolean includeLegacy(AndroidManifest appManifest) {
- return appManifest.supportsLegacyResourcesMode()
- && (this == legacy
- || this == both);
- }
-
- boolean includeBinary(AndroidManifest appManifest) {
- return appManifest.supportsBinaryResourcesMode()
- && (this == binary || this == best || this == both);
- }
- }
-
@Override
protected List<FrameworkMethod> getChildren() {
List<FrameworkMethod> children = new ArrayList<>();
@@ -222,19 +195,6 @@ public class RobolectricTestRunner extends SandboxTestRunner {
List<Sdk> sdksToRun = sdkPicker.selectSdks(configuration, appManifest);
RobolectricFrameworkMethod last = null;
for (Sdk sdk : sdksToRun) {
- if (resModeStrategy.includeLegacy(appManifest)) {
- children.add(
- last =
- new RobolectricFrameworkMethod(
- frameworkMethod.getMethod(),
- appManifest,
- sdk,
- configuration,
- ResourcesMode.LEGACY,
- resModeStrategy,
- alwaysIncludeVariantMarkersInName));
- }
- if (resModeStrategy.includeBinary(appManifest)) {
children.add(
last =
new RobolectricFrameworkMethod(
@@ -243,9 +203,7 @@ public class RobolectricTestRunner extends SandboxTestRunner {
sdk,
configuration,
ResourcesMode.BINARY,
- resModeStrategy,
alwaysIncludeVariantMarkersInName));
- }
}
if (last != null) {
last.dontIncludeVariantMarkersInTestName();
@@ -273,13 +231,6 @@ public class RobolectricTestRunner extends SandboxTestRunner {
InstrumentationConfiguration classLoaderConfig = createClassLoaderConfig(method);
ResourcesMode resourcesMode = roboMethod.getResourcesMode();
- if (resourcesMode == ResourcesMode.LEGACY && sdk.getApiLevel() > Build.VERSION_CODES.P) {
- System.err.println(
- "Failure for "
- + method.getName()
- + " because Robolectric doesn't support legacy resources mode after P");
- throw new AssertionError("Robolectric doesn't support legacy resources mode after P");
- }
LooperMode.Mode looperMode =
roboMethod.configuration == null
? Mode.LEGACY
@@ -323,12 +274,6 @@ public class RobolectricTestRunner extends SandboxTestRunner {
+ "; resources="
+ roboMethod.resourcesMode);
- if (roboMethod.resourcesMode == ResourcesMode.LEGACY) {
- Logger.warn(
- "Legacy resources mode is deprecated; see"
- + " http://robolectric.org/migrating/#migrating-to-40");
- }
-
roboMethod.setStuff(androidSandbox, androidSandbox.getTestEnvironment());
Class<TestLifecycle> cl = androidSandbox.bootstrappedClass(getTestLifecycleClass());
roboMethod.testLifecycle = ReflectionHelpers.newInstance(cl);
@@ -559,11 +504,6 @@ public class RobolectricTestRunner extends SandboxTestRunner {
"this should always be invoked on the HelperTestRunner!");
}
- @VisibleForTesting
- ResModeStrategy getResModeStrategy() {
- return ResModeStrategy.getFromProperties();
- }
-
public static class HelperTestRunner extends SandboxTestRunner.HelperTestRunner {
public HelperTestRunner(Class bootstrappedTestClass) throws InitializationError {
super(bootstrappedTestClass);
@@ -606,7 +546,6 @@ public class RobolectricTestRunner extends SandboxTestRunner {
@Nonnull private final AndroidManifest appManifest;
@Nonnull private final Configuration configuration;
@Nonnull private final ResourcesMode resourcesMode;
- @Nonnull private final ResModeStrategy defaultResModeStrategy;
@Nonnull private final Sdk sdk;
private final boolean alwaysIncludeVariantMarkersInName;
@@ -623,7 +562,6 @@ public class RobolectricTestRunner extends SandboxTestRunner {
other.getSdk(),
other.configuration,
other.resourcesMode,
- other.defaultResModeStrategy,
other.alwaysIncludeVariantMarkersInName);
includeVariantMarkersInTestName = other.includeVariantMarkersInTestName;
@@ -636,7 +574,6 @@ public class RobolectricTestRunner extends SandboxTestRunner {
@Nonnull Sdk sdk,
@Nonnull Configuration configuration,
@Nonnull ResourcesMode resourcesMode,
- @Nonnull ResModeStrategy defaultResModeStrategy,
boolean alwaysIncludeVariantMarkersInName) {
super(method);
@@ -644,7 +581,6 @@ public class RobolectricTestRunner extends SandboxTestRunner {
this.appManifest = appManifest;
this.configuration = configuration;
this.resourcesMode = resourcesMode;
- this.defaultResModeStrategy = defaultResModeStrategy;
this.alwaysIncludeVariantMarkersInName = alwaysIncludeVariantMarkersInName;
this.sdk = sdk;
}
@@ -657,10 +593,6 @@ public class RobolectricTestRunner extends SandboxTestRunner {
if (includeVariantMarkersInTestName || alwaysIncludeVariantMarkersInName) {
buf.append("[").append(getSdk().getApiLevel()).append("]");
-
- if (defaultResModeStrategy == ResModeStrategy.both) {
- buf.append("[").append(resourcesMode.name()).append("]");
- }
}
return buf.toString();
@@ -694,7 +626,7 @@ public class RobolectricTestRunner extends SandboxTestRunner {
}
public boolean isLegacy() {
- return resourcesMode == ResourcesMode.LEGACY;
+ return false;
}
public ResourcesMode getResourcesMode() {
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 6126b253a..f3a3f9ca7 100644
--- a/robolectric/src/main/java/org/robolectric/android/internal/AndroidTestEnvironment.java
+++ b/robolectric/src/main/java/org/robolectric/android/internal/AndroidTestEnvironment.java
@@ -130,7 +130,6 @@ public class AndroidTestEnvironment implements TestEnvironment {
this.shadowProviders = shadowProviders;
this.testEnvironmentLifecyclePlugins = lifecyclePlugins;
- RuntimeEnvironment.setUseLegacyResources(resourcesMode == ResourcesMode.LEGACY);
ReflectionHelpers.setStaticField(RuntimeEnvironment.class, "apiLevel", apiLevel);
}
diff --git a/robolectric/src/main/java/org/robolectric/internal/ResourcesMode.java b/robolectric/src/main/java/org/robolectric/internal/ResourcesMode.java
index bc2701c7c..b4b8d82a6 100644
--- a/robolectric/src/main/java/org/robolectric/internal/ResourcesMode.java
+++ b/robolectric/src/main/java/org/robolectric/internal/ResourcesMode.java
@@ -1,6 +1,5 @@
package org.robolectric.internal;
public enum ResourcesMode {
- BINARY,
- LEGACY
+ BINARY
}
diff --git a/robolectric/src/test/java/org/robolectric/RobolectricTestRunnerTest.java b/robolectric/src/test/java/org/robolectric/RobolectricTestRunnerTest.java
index 95f71c295..69b17a2f4 100644
--- a/robolectric/src/test/java/org/robolectric/RobolectricTestRunnerTest.java
+++ b/robolectric/src/test/java/org/robolectric/RobolectricTestRunnerTest.java
@@ -43,7 +43,6 @@ import org.junit.runner.notification.RunNotifier;
import org.junit.runners.JUnit4;
import org.junit.runners.MethodSorters;
import org.junit.runners.model.FrameworkMethod;
-import org.robolectric.RobolectricTestRunner.ResModeStrategy;
import org.robolectric.RobolectricTestRunner.RobolectricFrameworkMethod;
import org.robolectric.android.internal.AndroidTestEnvironment;
import org.robolectric.annotation.Config;
@@ -217,8 +216,7 @@ public class RobolectricTestRunnerTest {
mock(AndroidManifest.class),
sdkCollection.getSdk(16),
mock(Configuration.class),
- ResourcesMode.LEGACY,
- ResModeStrategy.legacy,
+ ResourcesMode.BINARY,
false);
RobolectricFrameworkMethod rfm17 =
new RobolectricFrameworkMethod(
@@ -226,8 +224,7 @@ public class RobolectricTestRunnerTest {
mock(AndroidManifest.class),
sdkCollection.getSdk(17),
mock(Configuration.class),
- ResourcesMode.LEGACY,
- ResModeStrategy.legacy,
+ ResourcesMode.BINARY,
false);
RobolectricFrameworkMethod rfm16b =
new RobolectricFrameworkMethod(
@@ -235,22 +232,11 @@ public class RobolectricTestRunnerTest {
mock(AndroidManifest.class),
sdkCollection.getSdk(16),
mock(Configuration.class),
- ResourcesMode.LEGACY,
- ResModeStrategy.legacy,
- false);
- RobolectricFrameworkMethod rfm16c =
- new RobolectricFrameworkMethod(
- method,
- mock(AndroidManifest.class),
- sdkCollection.getSdk(16),
- mock(Configuration.class),
ResourcesMode.BINARY,
- ResModeStrategy.legacy,
false);
assertThat(rfm16).isNotEqualTo(rfm17);
assertThat(rfm16).isEqualTo(rfm16b);
- assertThat(rfm16).isNotEqualTo(rfm16c);
assertThat(rfm16.hashCode()).isEqualTo(rfm16b.hashCode());
}
diff --git a/robolectric/src/test/java/org/robolectric/SingleSdkRobolectricTestRunner.java b/robolectric/src/test/java/org/robolectric/SingleSdkRobolectricTestRunner.java
index 1d35f8c0b..94bf451f4 100644
--- a/robolectric/src/test/java/org/robolectric/SingleSdkRobolectricTestRunner.java
+++ b/robolectric/src/test/java/org/robolectric/SingleSdkRobolectricTestRunner.java
@@ -45,11 +45,6 @@ public class SingleSdkRobolectricTestRunner extends RobolectricTestRunner {
return latestSandbox;
}
- @Override
- ResModeStrategy getResModeStrategy() {
- return ResModeStrategy.binary;
- }
-
public static class SingleSdkPicker implements SdkPicker {
private final Sdk sdk;
diff --git a/robolectric/src/test/java/org/robolectric/manifest/AndroidManifestTest.java b/robolectric/src/test/java/org/robolectric/manifest/AndroidManifestTest.java
index 3847ed031..51b809b69 100644
--- a/robolectric/src/test/java/org/robolectric/manifest/AndroidManifestTest.java
+++ b/robolectric/src/test/java/org/robolectric/manifest/AndroidManifestTest.java
@@ -242,19 +242,6 @@ public class AndroidManifestTest {
.isEqualTo(VERSION_CODES.JELLY_BEAN);
}
- /**
- * For Android O preview, apps are encouraged to use targetSdkVersion="O".
- *
- * @see <a href="http://google.com">https://developer.android.com/preview/migration.html</a>
- */
- @Test
- public void shouldReadTargetSDKVersionOPreview() throws Exception {
- assertThat(
- newConfigWith("TestAndroidManifestForPreview.xml", "android:targetSdkVersion=\"O\"")
- .getTargetSdkVersion())
- .isEqualTo(26);
- }
-
@Test
public void shouldReadProcessFromAndroidManifest() throws Exception {
assertThat(newConfig("TestAndroidManifestWithProcess.xml").getProcessName())
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothAdapterTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothAdapterTest.java
index b94d94e94..a9c3e8d81 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothAdapterTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowBluetoothAdapterTest.java
@@ -36,6 +36,8 @@ import android.content.Intent;
import android.os.Looper;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.LinkedBlockingQueue;
@@ -111,6 +113,27 @@ public class ShadowBluetoothAdapterTest {
}
@Test
+ @Config(minSdk = TIRAMISU)
+ public void canGetAndSetMostRecentlyConnectedDevices() {
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+
+ // By default return empty list for most recently connected devices
+ assertThat(adapter.getMostRecentlyConnectedDevices()).isEmpty();
+
+ // set most recently connected devices
+ BluetoothDevice remoteDevice1 = bluetoothAdapter.getRemoteDevice(MOCK_MAC_ADDRESS);
+ BluetoothDevice remoteDevice2 = bluetoothAdapter.getRemoteDevice(MOCK_MAC_ADDRESS);
+ List<BluetoothDevice> result = new ArrayList<>();
+ result.add(remoteDevice1);
+ result.add(remoteDevice2);
+ shadowOf(adapter).setMostRecentlyConnectedDevices(result);
+
+ assertThat(adapter.getMostRecentlyConnectedDevices()).hasSize(2);
+ assertThat(adapter.getMostRecentlyConnectedDevices())
+ .containsExactly(remoteDevice1, remoteDevice2);
+ }
+
+ @Test
@Config(minSdk = LOLLIPOP)
public void canGetBluetoothLeScanner() {
if (RuntimeEnvironment.getApiLevel() < M) {
@@ -868,4 +891,17 @@ public class ShadowBluetoothAdapterTest {
public void onLeScan(BluetoothDevice bluetoothDevice, int i, byte[] bytes) {}
};
}
+
+ @Config(minSdk = TIRAMISU)
+ @Test
+ public void canGetAndSetLeAudioSupport() {
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+
+ // By default LE feature is not supported
+ assertThat(adapter.isLeAudioSupported()).isEqualTo(BluetoothStatusCodes.FEATURE_NOT_SUPPORTED);
+
+ // set Le audio feature to supported.
+ shadowOf(adapter).setLeAudioSupported(BluetoothStatusCodes.FEATURE_SUPPORTED);
+ assertThat(adapter.isLeAudioSupported()).isEqualTo(BluetoothStatusCodes.FEATURE_SUPPORTED);
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaActionSoundTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaActionSoundTest.java
index a240ab221..ad6aeebdb 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaActionSoundTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowMediaActionSoundTest.java
@@ -4,6 +4,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.media.MediaActionSound;
import android.os.Build;
+import android.os.Build.VERSION_CODES;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -74,4 +75,22 @@ public final class ShadowMediaActionSoundTest {
assertThat(ShadowMediaActionSound.getPlayCount(MediaActionSound.SHUTTER_CLICK)).isEqualTo(3);
}
+
+ @Test
+ @Config(minSdk = VERSION_CODES.TIRAMISU)
+ public void mustPlayShutterSound_defaultFalse() {
+ assertThat(MediaActionSound.mustPlayShutterSound()).isFalse();
+ }
+
+ @Test
+ @Config(minSdk = VERSION_CODES.TIRAMISU)
+ public void mustPlayShutterSound_overrident_correctValue() {
+ ShadowMediaActionSound.setMustPlayShutterSound(true);
+
+ assertThat(MediaActionSound.mustPlayShutterSound()).isTrue();
+
+ ShadowMediaActionSound.setMustPlayShutterSound(false);
+
+ assertThat(MediaActionSound.mustPlayShutterSound()).isFalse();
+ }
}
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowStorageManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowStorageManagerTest.java
index 84120e001..ad410660e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowStorageManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowStorageManagerTest.java
@@ -2,6 +2,7 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.N;
import static android.os.Build.VERSION_CODES.TIRAMISU;
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.RuntimeEnvironment.getApplication;
import static org.robolectric.Shadows.shadowOf;
@@ -91,10 +92,17 @@ public class ShadowStorageManagerTest {
}
@Test
- @Config(minSdk = N)
+ @Config(minSdk = N, maxSdk = UPSIDE_DOWN_CAKE)
public void isUserKeyUnlocked() {
shadowOf(getApplication().getSystemService(UserManager.class)).setUserUnlocked(true);
- assertThat(StorageManager.isUserKeyUnlocked(0)).isTrue();
+ // Use reflection, as this method is planned to be removed from StorageManager in V.
+ assertThat(
+ (boolean)
+ ReflectionHelpers.callStaticMethod(
+ StorageManager.class,
+ "isUserKeyUnlocked",
+ ReflectionHelpers.ClassParameter.from(int.class, 0)))
+ .isTrue();
}
private StorageVolume buildAndGetStorageVolume(File file, String description) {
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowTelecomManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowTelecomManagerTest.java
index f1e6dadc1..826d36391 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowTelecomManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowTelecomManagerTest.java
@@ -130,6 +130,21 @@ public class ShadowTelecomManagerTest {
}
@Test
+ @Config(minSdk = M)
+ public void enableNonRegisteredAccountDoesNothing() {
+ PhoneAccountHandle accountHandle1 = createHandle("a.package", "OtherConnectionService", "id1");
+ telecomService.registerPhoneAccount(
+ PhoneAccount.builder(accountHandle1, "another_package").build());
+
+ // Attempt to enable phone account that hasn't been registered should do nothing.
+ PhoneAccountHandle accountHandle2 =
+ createHandle("some.other.package", "OtherConnectionService", "id2");
+ telecomService.enablePhoneAccount(accountHandle2, /* isEnabled= */ true);
+
+ assertThat(telecomService.getPhoneAccount(accountHandle1).isEnabled()).isFalse();
+ }
+
+ @Test
public void getPhoneAccountsSupportingScheme() {
PhoneAccountHandle handleMatchingScheme = createHandle("id1");
telecomService.registerPhoneAccount(
diff --git a/robolectric/src/test/java/org/robolectric/shadows/ShadowVirtualDeviceManagerTest.java b/robolectric/src/test/java/org/robolectric/shadows/ShadowVirtualDeviceManagerTest.java
index 98db027df..f11cf763e 100644
--- a/robolectric/src/test/java/org/robolectric/shadows/ShadowVirtualDeviceManagerTest.java
+++ b/robolectric/src/test/java/org/robolectric/shadows/ShadowVirtualDeviceManagerTest.java
@@ -62,6 +62,20 @@ public class ShadowVirtualDeviceManagerTest {
}
@Test
+ public void testIsClosed() {
+ VirtualDevice virtualDevice =
+ virtualDeviceManager.createVirtualDevice(
+ 0, new VirtualDeviceParams.Builder().setName("foo").build());
+ ShadowVirtualDevice shadowDevice = Shadow.extract(virtualDevice);
+
+ assertThat(shadowDevice.isClosed()).isFalse();
+
+ virtualDevice.close();
+
+ assertThat(shadowDevice.isClosed()).isTrue();
+ }
+
+ @Test
public void testIsValidVirtualDeviceId() {
VirtualDevice virtualDevice =
virtualDeviceManager.createVirtualDevice(
diff --git a/sandbox/src/main/java/org/robolectric/config/AndroidConfigurer.java b/sandbox/src/main/java/org/robolectric/config/AndroidConfigurer.java
index c03b88262..1fb7a98d2 100644
--- a/sandbox/src/main/java/org/robolectric/config/AndroidConfigurer.java
+++ b/sandbox/src/main/java/org/robolectric/config/AndroidConfigurer.java
@@ -106,6 +106,10 @@ public class AndroidConfigurer {
// Instrumenting these classes causes a weird failure.
builder.doNotInstrumentClass("android.R").doNotInstrumentClass("android.R$styleable");
+ // Instrumenting this Exceptions causes "java.lang.NegativeArraySizeException: -2" and
+ // leads to java.lang.NoClassDefFoundError.
+ builder.doNotInstrumentClass("android.app.RecoverableSecurityException");
+
builder
.addInstrumentedPackage("dalvik.")
.addInstrumentedPackage("libcore.")
diff --git a/shadows/framework/Android.bp b/shadows/framework/Android.bp
index 8c050b589..8e9f0e13b 100644
--- a/shadows/framework/Android.bp
+++ b/shadows/framework/Android.bp
@@ -39,16 +39,11 @@ java_library_host {
"Robolectric_utils_upstream",
"Robolectric_utils_reflector_upstream",
"auto_value_annotations",
- //jetpack
- //"androidx.annotation_annotation-nodeps",
"jsr305",
"icu4j",
"robolectric-accessibility-test-framework-2.1",
"robolectric-javax.annotation-api-1.2",
- //"hamcrest-library",
- //"hamcrest",
- //"stub-annotations",
"robolectric-sqlite4java-0.282",
"asm-commons-9.2",
"guava",
@@ -56,9 +51,12 @@ java_library_host {
"asm-9.2",
//standard tools
"error_prone_annotations",
- //"grpc-java-netty-shaded",
// aar files that make up android and jetpack
- "robolectric-host-android_all_upstream",
+ "robolectric-host-android_all",
+ "robolectric-host-androidx-test-core_upstream",
+ //"robolectric-host-androidx-test-ext-junit_upstream",
+ "robolectric-host-androidx-test-monitor_upstream",
+ //"robolectric-host-androidx-test-runner_upstream",
],
plugins: [
"auto_value_plugin_1.9",
diff --git a/shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java b/shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java
index a58fd7069..cc7c1d457 100644
--- a/shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java
+++ b/shadows/framework/src/main/java/org/robolectric/RuntimeEnvironment.java
@@ -53,7 +53,6 @@ public class RuntimeEnvironment {
private static Path androidFrameworkJar;
public static Path compileTimeSystemResourcesFile;
- private static boolean useLegacyResources;
private static Supplier<Application> applicationSupplier;
private static final Object supplierLock = new Object();
@@ -341,16 +340,6 @@ public class RuntimeEnvironment {
*/
@Deprecated
public static boolean useLegacyResources() {
- return useLegacyResources;
- }
-
- /**
- * Internal only.
- *
- * @deprecated Do not use.
- */
- @Deprecated
- public static void setUseLegacyResources(boolean useLegacyResources) {
- RuntimeEnvironment.useLegacyResources = useLegacyResources;
+ return false;
}
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBinder.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBinder.java
index a5f99b1ee..bb0cd86f3 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBinder.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBinder.java
@@ -47,7 +47,7 @@ public class ShadowBinder {
}
@Implementation
- protected static final int getCallingPid() {
+ protected static int getCallingPid() {
if (callingPid != null) {
return callingPid;
}
@@ -55,7 +55,7 @@ public class ShadowBinder {
}
@Implementation
- protected static final int getCallingUid() {
+ protected static int getCallingUid() {
if (callingUid != null) {
return callingUid;
}
@@ -71,7 +71,7 @@ public class ShadowBinder {
* @throws IllegalStateException if no UID has been set
*/
@Implementation(minSdk = Q)
- protected static final int getCallingUidOrThrow() {
+ protected static int getCallingUidOrThrow() {
if (callingUid != null) {
return callingUid;
}
@@ -81,7 +81,7 @@ public class ShadowBinder {
}
@Implementation(minSdk = JELLY_BEAN_MR1)
- protected static final UserHandle getCallingUserHandle() {
+ protected static UserHandle getCallingUserHandle() {
if (callingUserHandle != null) {
return callingUserHandle;
}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java
index b3cb8f16d..5e89a77b6 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java
@@ -90,6 +90,7 @@ public class ShadowBluetoothAdapter {
private static final Map<String, BluetoothDevice> deviceCache = new HashMap<>();
private Set<BluetoothDevice> bondedDevices = new HashSet<BluetoothDevice>();
+ private List<BluetoothDevice> mostRecentlyConnectedDevices = new ArrayList<>();
private Set<LeScanCallback> leScanCallbacks = new HashSet<LeScanCallback>();
private boolean isDiscovering;
private String address;
@@ -99,6 +100,7 @@ public class ShadowBluetoothAdapter {
private Duration discoverableTimeout;
private boolean isBleScanAlwaysAvailable = true;
private boolean isMultipleAdvertisementSupported = true;
+ private int isLeAudioSupported = BluetoothStatusCodes.FEATURE_NOT_SUPPORTED;
private boolean isLeExtendedAdvertisingSupported = true;
private boolean isOverridingProxyBehavior;
private final Map<Integer, Integer> profileConnectionStateData = new HashMap<>();
@@ -141,12 +143,24 @@ public class ShadowBluetoothAdapter {
ClassParameter.from(AttributionSource.class, attributionSource));
}
+ /** Sets whether the Le Audio is supported or not. Minimum sdk version required is TIRAMISU. */
+ public void setLeAudioSupported(int supported) {
+ isLeAudioSupported = supported;
+ }
+
+ @Implementation(minSdk = VERSION_CODES.TIRAMISU)
+ protected int isLeAudioSupported() {
+ return isLeAudioSupported;
+ }
+
/** Determines if getDefaultAdapter() returns the default local adapter (true) or null (false). */
public static void setIsBluetoothSupported(boolean supported) {
isBluetoothSupported = supported;
}
- /** @deprecated use real BluetoothLeAdvertiser instead */
+ /**
+ * @deprecated use real BluetoothLeAdvertiser instead
+ */
@Deprecated
public void setBluetoothLeAdvertiser(BluetoothLeAdvertiser advertiser) {
if (RuntimeEnvironment.getApiLevel() <= VERSION_CODES.LOLLIPOP_MR1) {
@@ -166,6 +180,15 @@ public class ShadowBluetoothAdapter {
return deviceCache.get(address);
}
+ public void setMostRecentlyConnectedDevices(List<BluetoothDevice> devices) {
+ mostRecentlyConnectedDevices = devices;
+ }
+
+ @Implementation(minSdk = TIRAMISU)
+ protected List<BluetoothDevice> getMostRecentlyConnectedDevices() {
+ return mostRecentlyConnectedDevices;
+ }
+
@Implementation
protected Set<BluetoothDevice> getBondedDevices() {
return Collections.unmodifiableSet(bondedDevices);
@@ -179,26 +202,26 @@ public class ShadowBluetoothAdapter {
protected BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(
String serviceName, UUID uuid) {
return ShadowBluetoothServerSocket.newInstance(
- BluetoothSocket.TYPE_RFCOMM, /*auth=*/ false, /*encrypt=*/ false, new ParcelUuid(uuid));
+ BluetoothSocket.TYPE_RFCOMM, /* auth= */ false, /* encrypt= */ false, new ParcelUuid(uuid));
}
@Implementation
protected BluetoothServerSocket listenUsingRfcommWithServiceRecord(String serviceName, UUID uuid)
throws IOException {
return ShadowBluetoothServerSocket.newInstance(
- BluetoothSocket.TYPE_RFCOMM, /*auth=*/ false, /*encrypt=*/ true, new ParcelUuid(uuid));
+ BluetoothSocket.TYPE_RFCOMM, /* auth= */ false, /* encrypt= */ true, new ParcelUuid(uuid));
}
@Implementation(minSdk = Q)
protected BluetoothServerSocket listenUsingInsecureL2capChannel() throws IOException {
return ShadowBluetoothServerSocket.newInstance(
- BluetoothSocket.TYPE_L2CAP, /*auth=*/ false, /*encrypt=*/ true, /*uuid=*/ null);
+ BluetoothSocket.TYPE_L2CAP, /* auth= */ false, /* encrypt= */ true, /* uuid= */ null);
}
@Implementation(minSdk = Q)
protected BluetoothServerSocket listenUsingL2capChannel() throws IOException {
return ShadowBluetoothServerSocket.newInstance(
- BluetoothSocket.TYPE_L2CAP, /*auth=*/ false, /*encrypt=*/ true, /*uuid=*/ null);
+ BluetoothSocket.TYPE_L2CAP, /* auth= */ false, /* encrypt= */ true, /* uuid= */ null);
}
@Implementation
@@ -464,7 +487,9 @@ public class ShadowBluetoothAdapter {
this.state = state;
}
- /** @deprecated Use {@link BluetoothAdapter#enable()} or {@link BluetoothAdapter#disable()}. */
+ /**
+ * @deprecated Use {@link BluetoothAdapter#enable()} or {@link BluetoothAdapter#disable()}.
+ */
@Deprecated
public void setEnabled(boolean enabled) {
if (enabled) {
@@ -558,7 +583,7 @@ public class ShadowBluetoothAdapter {
* Overrides behavior of {@link closeProfileProxy} if {@link
* ShadowBluetoothAdapter#setProfileProxy} has been previously called.
*
- * If the given non-null BluetoothProfile {@code proxy} was previously set for the given {@code
+ * <p>If the given non-null BluetoothProfile {@code proxy} was previously set for the given {@code
* profile} by {@link ShadowBluetoothAdapter#setProfileProxy}, this proxy will be "deactivated".
*/
@Implementation
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHidlSupport.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHidlSupport.java
new file mode 100644
index 000000000..78f88891e
--- /dev/null
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHidlSupport.java
@@ -0,0 +1,16 @@
+package org.robolectric.shadows;
+
+import android.os.HidlSupport;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.versioning.AndroidVersions.V;
+
+@SuppressWarnings("NewApi")
+@Implements(value = HidlSupport.class, isInAndroidSdk = false, minSdk = V.SDK_INT)
+public class ShadowHidlSupport {
+
+ @Implementation
+ protected static boolean isHidlSupported() {
+ return true;
+ }
+}
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowKeyCharacterMap.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowKeyCharacterMap.java
index 7ce4c603b..ea29a43dc 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowKeyCharacterMap.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowKeyCharacterMap.java
@@ -64,6 +64,7 @@ public class ShadowKeyCharacterMap {
CHAR_TO_KEY_CODE.put(',', KeyEvent.KEYCODE_COMMA);
CHAR_TO_KEY_CODE.put('[', KeyEvent.KEYCODE_LEFT_BRACKET);
CHAR_TO_KEY_CODE.put(']', KeyEvent.KEYCODE_RIGHT_BRACKET);
+ CHAR_TO_KEY_CODE.put(';', KeyEvent.KEYCODE_SEMICOLON);
CHAR_TO_KEY_CODE.put('\'', KeyEvent.KEYCODE_APOSTROPHE);
CHAR_TO_KEY_CODE.put(')', KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN);
CHAR_TO_KEY_CODE.put('(', KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN);
@@ -76,14 +77,23 @@ public class ShadowKeyCharacterMap {
CHAR_TO_KEY_CODE.put('\n', KeyEvent.KEYCODE_ENTER);
CHAR_TO_KEY_CODE_SHIFT_ON.put('_', KeyEvent.KEYCODE_MINUS);
+ CHAR_TO_KEY_CODE_SHIFT_ON.put('+', KeyEvent.KEYCODE_EQUALS);
CHAR_TO_KEY_CODE_SHIFT_ON.put('{', KeyEvent.KEYCODE_LEFT_BRACKET);
CHAR_TO_KEY_CODE_SHIFT_ON.put('}', KeyEvent.KEYCODE_RIGHT_BRACKET);
+ CHAR_TO_KEY_CODE_SHIFT_ON.put(':', KeyEvent.KEYCODE_SEMICOLON);
CHAR_TO_KEY_CODE_SHIFT_ON.put('\"', KeyEvent.KEYCODE_APOSTROPHE);
+ CHAR_TO_KEY_CODE_SHIFT_ON.put(')', KeyEvent.KEYCODE_0);
CHAR_TO_KEY_CODE_SHIFT_ON.put('!', KeyEvent.KEYCODE_1);
+ CHAR_TO_KEY_CODE_SHIFT_ON.put('@', KeyEvent.KEYCODE_2);
+ CHAR_TO_KEY_CODE_SHIFT_ON.put('#', KeyEvent.KEYCODE_3);
CHAR_TO_KEY_CODE_SHIFT_ON.put('$', KeyEvent.KEYCODE_4);
CHAR_TO_KEY_CODE_SHIFT_ON.put('%', KeyEvent.KEYCODE_5);
CHAR_TO_KEY_CODE_SHIFT_ON.put('^', KeyEvent.KEYCODE_6);
CHAR_TO_KEY_CODE_SHIFT_ON.put('&', KeyEvent.KEYCODE_7);
+ CHAR_TO_KEY_CODE_SHIFT_ON.put('*', KeyEvent.KEYCODE_8);
+ CHAR_TO_KEY_CODE_SHIFT_ON.put('(', KeyEvent.KEYCODE_9);
+ CHAR_TO_KEY_CODE_SHIFT_ON.put('>', KeyEvent.KEYCODE_PERIOD);
+ CHAR_TO_KEY_CODE_SHIFT_ON.put('<', KeyEvent.KEYCODE_COMMA);
CHAR_TO_KEY_CODE_SHIFT_ON.put('?', KeyEvent.KEYCODE_SLASH);
CHAR_TO_KEY_CODE_SHIFT_ON.put('|', KeyEvent.KEYCODE_BACKSLASH);
CHAR_TO_KEY_CODE_SHIFT_ON.put('~', KeyEvent.KEYCODE_GRAVE);
@@ -132,6 +142,7 @@ public class ShadowKeyCharacterMap {
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_COMMA, ',');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_LEFT_BRACKET, '[');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_RIGHT_BRACKET, ']');
+ KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_SEMICOLON, ';');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_APOSTROPHE, '\'');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN, ')');
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN, '(');
@@ -144,14 +155,23 @@ public class ShadowKeyCharacterMap {
KEY_CODE_TO_CHAR.put(KeyEvent.KEYCODE_ENTER, '\n');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_MINUS, '_');
+ KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_EQUALS, '+');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_LEFT_BRACKET, '{');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_RIGHT_BRACKET, '}');
+ KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_SEMICOLON, ':');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_APOSTROPHE, '\"');
+ KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_0, ')');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_1, '!');
+ KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_2, '@');
+ KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_3, '#');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_4, '$');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_5, '%');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_6, '^');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_7, '&');
+ KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_8, '*');
+ KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_9, '(');
+ KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_PERIOD, '>');
+ KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_COMMA, '<');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_SLASH, '?');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_BACKSLASH, '|');
KEY_CODE_TO_CHAR_SHIFT_ON.put(KeyEvent.KEYCODE_GRAVE, '~');
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaActionSound.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaActionSound.java
index 7d34663d4..82e405054 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaActionSound.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowMediaActionSound.java
@@ -1,5 +1,6 @@
package org.robolectric.shadows;
+import static android.os.Build.VERSION_CODES.TIRAMISU;
import static org.robolectric.util.reflector.Reflector.reflector;
import android.media.MediaActionSound;
@@ -28,6 +29,9 @@ public class ShadowMediaActionSound {
private static final int NUM_SOUNDS = ALL_SOUNDS.length;
private static final Map<Integer, AtomicInteger> playCount = initializePlayCountMap();
+ @SuppressWarnings("NonFinalStaticField")
+ private static boolean mustPlayShutterSoundInternal = false;
+
private static final HashMap<Integer, AtomicInteger> initializePlayCountMap() {
HashMap<Integer, AtomicInteger> playCount = new HashMap<>();
for (int sound : ALL_SOUNDS) {
@@ -45,6 +49,11 @@ public class ShadowMediaActionSound {
return playCount.get(soundName).get();
}
+ /** Sets the value returned by {@link MediaActionSound#mustPlayShutterSound()}. */
+ public static void setMustPlayShutterSound(boolean mustPlayShutterSound) {
+ mustPlayShutterSoundInternal = mustPlayShutterSound;
+ }
+
@Resetter
public static void reset() {
synchronized (playCount) {
@@ -62,6 +71,11 @@ public class ShadowMediaActionSound {
playCount.get(soundName).incrementAndGet();
}
+ @Implementation(minSdk = TIRAMISU)
+ protected static boolean mustPlayShutterSound() {
+ return mustPlayShutterSoundInternal;
+ }
+
@ForType(MediaActionSound.class)
interface MediaActionSoundReflector {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeHardwareRenderer.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeHardwareRenderer.java
index 1bfaa90e7..408ea1c27 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeHardwareRenderer.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeHardwareRenderer.java
@@ -344,11 +344,13 @@ public class ShadowNativeHardwareRenderer {
HardwareRendererNatives.nAllocateBuffers(nativeProxy);
}
- @Implementation
+ @Implementation(maxSdk = U.SDK_INT)
protected static void nSetForceDark(long nativeProxy, boolean enabled) {
HardwareRendererNatives.nSetForceDark(nativeProxy, enabled);
}
+ // TODO(brettchabot): add support for V nSetForceDark(long, int)
+
@Implementation(minSdk = S)
protected static void nSetDisplayDensityDpi(int densityDpi) {
HardwareRendererNatives.nSetDisplayDensityDpi(densityDpi);
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativePaint.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativePaint.java
index 476477679..34cb9ebd9 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativePaint.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativePaint.java
@@ -868,30 +868,32 @@ public class ShadowNativePaint {
advancesIndex);
}
+ /** Requires loose signatures because of RunInfo parameter */
@Implementation(minSdk = V.SDK_INT)
protected static float nGetRunCharacterAdvance(
- long paintPtr,
- char[] text,
- int start,
- int end,
- int contextStart,
- int contextEnd,
- boolean isRtl,
- int offset,
- float[] advances,
- int advancesIndex,
- RectF drawingBounds) {
+ Object /* long */ paintPtr,
+ Object /* char[] */ text,
+ Object /* int */ start,
+ Object /* int */ end,
+ Object /* int */ contextStart,
+ Object /* int */ contextEnd,
+ Object /* boolean */ isRtl,
+ Object /* int */ offset,
+ Object /* float[] */ advances,
+ Object /* int */ advancesIndex,
+ Object /* RectF */ drawingBounds,
+ Object /* RunInfo */ runInfo) {
return nGetRunCharacterAdvance(
- paintPtr,
- text,
- start,
- end,
- contextStart,
- contextEnd,
- isRtl,
- offset,
- advances,
- advancesIndex);
+ (long) paintPtr,
+ (char[]) text,
+ (int) start,
+ (int) end,
+ (int) contextStart,
+ (int) contextEnd,
+ (boolean) isRtl,
+ (int) offset,
+ (float[]) advances,
+ (int) advancesIndex);
}
/** Shadow picker for {@link Paint}. */
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 d56a7d7e5..e5bbc8287 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java
@@ -577,28 +577,29 @@ public class ShadowPaint {
@Implementation(minSdk = V.SDK_INT)
protected static float nGetRunCharacterAdvance(
- long paintPtr,
- char[] text,
- int start,
- int end,
- int contextStart,
- int contextEnd,
- boolean isRtl,
- int offset,
- float[] advances,
- int advancesIndex,
- RectF drawingBounds) {
+ Object /* long */ paintPtr,
+ Object /* char[] */ text,
+ Object /* int */ start,
+ Object /* int */ end,
+ Object /* int */ contextStart,
+ Object /* int */ contextEnd,
+ Object /* boolean */ isRtl,
+ Object /* int */ offset,
+ Object /* float[] */ advances,
+ Object /* int */ advancesIndex,
+ Object /* RectF */ drawingBounds,
+ Object /* RunInfo */ runInfo) {
return nGetRunCharacterAdvance(
- paintPtr,
- text,
- start,
- end,
- contextStart,
- contextEnd,
- isRtl,
- offset,
- advances,
- advancesIndex);
+ (long) paintPtr,
+ (char[]) text,
+ (int) start,
+ (int) end,
+ (int) contextStart,
+ (int) contextEnd,
+ (boolean) isRtl,
+ (int) offset,
+ (float[]) advances,
+ (int) advancesIndex);
}
@Implementation(minSdk = N, maxSdk = O_MR1)
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java
index a597c971f..1dfbfeccf 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowServiceManager.java
@@ -95,6 +95,7 @@ import com.android.internal.app.IBatteryStats;
import com.android.internal.app.ISoundTriggerService;
import com.android.internal.app.IVoiceInteractionManagerService;
import com.android.internal.appwidget.IAppWidgetService;
+import com.android.internal.compat.IPlatformCompat;
import com.android.internal.os.IDropBoxManagerService;
import com.android.internal.statusbar.IStatusBar;
import com.android.internal.telephony.ITelephony;
@@ -207,6 +208,7 @@ public class ShadowServiceManager {
addBinderService(Context.AUTH_SERVICE, IAuthService.class);
addBinderService(Context.TETHERING_SERVICE, ITetheringConnector.class);
addBinderService("telephony.registry", ITelephonyRegistry.class);
+ addBinderService(Context.PLATFORM_COMPAT_SERVICE, IPlatformCompat.class);
}
if (RuntimeEnvironment.getApiLevel() >= S) {
addBinderService("permissionmgr", IPermissionManager.class);
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java
index 552d3101f..16cad3b6a 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSettings.java
@@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableMap;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@@ -565,6 +566,26 @@ public class ShadowSettings {
lockScreenAllowPrivateNotifications ? 1 : 0);
}
+ /**
+ * Shadow for {@link Settings.Config}.
+ *
+ * <p>This shadow is primarily to support {@link android.provider.DeviceConfig}, which queries
+ * {@link Settings.Config}. {@link android.provider.DeviceConfig} is pure Java code so it's not
+ * necessary to shadow that directly.
+ *
+ * <p>The underlying implementation calls into a system content provider. Starting in Android U,
+ * the internal logic of Activity is querying DeviceConfig, so to avoid crashes we need to make
+ * DeviceConfig a no-op.
+ */
+ @Implements(value = Settings.Config.class, isInAndroidSdk = false)
+ public static class ShadowConfig {
+ @Implementation(minSdk = R)
+ protected static Map<String, String> getStrings(
+ ContentResolver resolver, String namespace, List<String> names) {
+ return ImmutableMap.of();
+ }
+ }
+
@Resetter
public static void reset() {
canDrawOverlays = false;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStorageManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStorageManager.java
index 5bd08191e..929c36aef 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStorageManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStorageManager.java
@@ -3,6 +3,7 @@ package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.N;
import static android.os.Build.VERSION_CODES.TIRAMISU;
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
import android.os.UserManager;
import android.os.storage.StorageManager;
@@ -101,8 +102,9 @@ public class ShadowStorageManager {
isFileEncryptionSupported = isSupported;
}
+ // Use maxSdk=U, as this method is planned to be removed from StorageManager in V.
@HiddenApi
- @Implementation(minSdk = N)
+ @Implementation(minSdk = N, maxSdk = UPSIDE_DOWN_CAKE)
protected static boolean isUserKeyUnlocked(int userId) {
ShadowUserManager extract =
Shadow.extract(RuntimeEnvironment.getApplication().getSystemService(UserManager.class));
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelecomManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelecomManager.java
index 152bbdd37..87dbf83e1 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelecomManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelecomManager.java
@@ -6,7 +6,6 @@ import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.N;
import static android.os.Build.VERSION_CODES.O;
import static android.os.Build.VERSION_CODES.R;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Verify.verifyNotNull;
import android.annotation.SystemApi;
@@ -653,7 +652,10 @@ public class ShadowTelecomManager {
@Implementation(minSdk = M)
@HiddenApi
public void enablePhoneAccount(PhoneAccountHandle handle, boolean isEnabled) {
- checkNotNull(getPhoneAccount(handle)).setIsEnabled(isEnabled);
+ if (getPhoneAccount(handle) == null) {
+ return;
+ }
+ getPhoneAccount(handle).setIsEnabled(isEnabled);
}
/**
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVirtualDeviceManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVirtualDeviceManager.java
index a945031ce..ea978511f 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVirtualDeviceManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowVirtualDeviceManager.java
@@ -17,6 +17,7 @@ import android.content.Context;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.IntConsumer;
import java.util.stream.Collectors;
@@ -125,6 +126,7 @@ public class ShadowVirtualDeviceManager {
private int deviceId;
private PendingIntent pendingIntent;
private Integer pendingIntentResultCode = LAUNCH_SUCCESS;
+ private final AtomicBoolean isClosed = new AtomicBoolean(false);
@Implementation
protected void __constructor__(
@@ -150,7 +152,13 @@ public class ShadowVirtualDeviceManager {
/** Prevents a NPE when calling .close() on a VirtualDevice in unit tests. */
@Implementation
- protected void close() {}
+ protected void close() {
+ isClosed.set(true);
+ }
+
+ public boolean isClosed() {
+ return isClosed.get();
+ }
VirtualDeviceParams getParams() {
return params;
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/WifiUsabilityStatsEntryBuilder.java b/shadows/framework/src/main/java/org/robolectric/shadows/WifiUsabilityStatsEntryBuilder.java
index f50eba29f..37b3f8d65 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/WifiUsabilityStatsEntryBuilder.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/WifiUsabilityStatsEntryBuilder.java
@@ -2,7 +2,6 @@ package org.robolectric.shadows;
import android.net.wifi.WifiUsabilityStatsEntry;
import android.net.wifi.WifiUsabilityStatsEntry.ContentionTimeStats;
-import android.net.wifi.WifiUsabilityStatsEntry.LinkStats;
import android.net.wifi.WifiUsabilityStatsEntry.RadioStats;
import android.net.wifi.WifiUsabilityStatsEntry.RateStats;
import android.os.Build.VERSION_CODES;
diff --git a/shadows/httpclient/Android.bp b/shadows/httpclient/Android.bp
index 526ba2620..29b89f9fc 100644
--- a/shadows/httpclient/Android.bp
+++ b/shadows/httpclient/Android.bp
@@ -21,7 +21,7 @@ java_library_host {
"robolectric-httpclient-4.0.3",
"robolectric-httpcore-4.0.1",
"robolectric-javax.annotation-api-1.2",
- "robolectric-host-android_all_upstream",
+ "robolectric-host-android_all",
"robolectric-host-org_apache_http_legacy_upstream",
],
plugins: ["Robolectric_processor_upstream"],
@@ -66,7 +66,7 @@ java_test_host {
"jsr305",
"grpc-java-netty-shaded",
//"grpc-netty-shaded-1.16.1-jar",
- "robolectric-host-android_all_upstream",
+ "robolectric-host-android_all",
"robolectric-host-org_apache_http_legacy_upstream",
"robolectric-host-androidx-test-ext-junit_upstream",
],
diff --git a/shadows/multidex/Android.bp b/shadows/multidex/Android.bp
index 91d3379c0..c8e214aed 100644
--- a/shadows/multidex/Android.bp
+++ b/shadows/multidex/Android.bp
@@ -18,7 +18,7 @@ java_library_host {
"Robolectric_shadowapi_upstream",
"robolectric-host-android-support-multidex_upstream",
"robolectric-javax.annotation-api-1.2",
- "robolectric-host-android_all_upstream",
+ "robolectric-host-android_all",
],
plugins: ["Robolectric_processor_upstream"],
javacflags: ["-Aorg.robolectric.annotation.processing.shadowPackage=org.robolectric.shadows.multidex"],
diff --git a/shadows/playservices/Android.bp b/shadows/playservices/Android.bp
index 4b6635e65..e63268c40 100644
--- a/shadows/playservices/Android.bp
+++ b/shadows/playservices/Android.bp
@@ -10,7 +10,7 @@
// "Robolectric_shadowapi_upstream",
// "robolectric-javax.annotation-api-1.2",
// "guava",
-// "robolectric-host-android_all_upstream",
+// "robolectric-host-android_all",
// compileOnly "com.android.support:support-fragment:28.0.0"
// compileOnly "com.google.android.gms:play-services-base:8.4.0"
diff --git a/shadows/versioning/Android.bp b/shadows/versioning/Android.bp
index 98a1ad353..3d44f1157 100644
--- a/shadows/versioning/Android.bp
+++ b/shadows/versioning/Android.bp
@@ -20,7 +20,7 @@ java_library_host {
"Robolectric_utils_upstream",
"jsr305",
],
- libs: ["robolectric-host-android_all_upstream"],
+ libs: ["robolectric-host-android_all"],
}
//#############################################
diff --git a/soong/Android.bp b/soong/Android.bp
new file mode 100644
index 000000000..d725fd118
--- /dev/null
+++ b/soong/Android.bp
@@ -0,0 +1,32 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "external_robolectric-shadows_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["external_robolectric_license"],
+}
+
+bootstrap_go_package {
+ name: "soong-robolectric",
+ pkgPath: "android/soong/robolectric",
+ srcs: ["robolectric.go"],
+ pluginFor: ["soong_build"],
+ deps: [
+ "soong-android",
+ ],
+}
diff --git a/soong/robolectric.go b/soong/robolectric.go
new file mode 100644
index 000000000..cadeb0fad
--- /dev/null
+++ b/soong/robolectric.go
@@ -0,0 +1,101 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package robolectric
+
+import (
+ "fmt"
+ "strings"
+
+ "android/soong/android"
+)
+
+var pctx = android.NewPackageContext("android/soong/robolectric")
+
+func init() {
+ pctx.Import("android/soong/android")
+ android.RegisterModuleType("robolectric_build_props", buildPropsFactory)
+}
+
+type buildProps struct {
+ android.ModuleBase
+ output android.WritablePath
+}
+
+var _ android.SourceFileProducer = (*buildProps)(nil)
+
+func (b *buildProps) Srcs() android.Paths {
+ return android.Paths{b.output}
+}
+
+func (b *buildProps) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+
+ displayID := fmt.Sprintf("robolectric %s %s",
+ ctx.Config().PlatformVersionName(),
+ ctx.Config().BuildId())
+
+ lines := []string{
+ "# build properties autogenerated by robolectric.go",
+ "",
+ "ro.build.id=" + ctx.Config().BuildId(),
+ "ro.build.display.id=" + displayID,
+ "ro.product.name=robolectric",
+ "ro.product.device=robolectric",
+ "ro.product.board=robolectric",
+ "ro.product.manufacturer=robolectric",
+ "ro.product.brand=robolectric",
+ "ro.product.model=robolectric",
+ "ro.hardware=robolectric",
+ "ro.build.version.security_patch=" + ctx.Config().PlatformSecurityPatch(),
+ "ro.build.version.sdk=" + ctx.Config().PlatformSdkVersion().String(),
+ "ro.build.version.release=" + ctx.Config().PlatformVersionName(),
+ "ro.build.version.preview_sdk=" + ctx.Config().PlatformPreviewSdkVersion(),
+ // We don't have the API fingerprint available, just use the preview SDK version.
+ "ro.build.version.preview_sdk_fingerprint=" + ctx.Config().PlatformPreviewSdkVersion(),
+ "ro.build.version.codename=" + ctx.Config().PlatformSdkCodename(),
+ "ro.build.version.all_codenames=" + strings.Join(ctx.Config().PlatformVersionActiveCodenames(), ","),
+ "ro.build.version.min_supported_target_sdk=" + ctx.Config().PlatformMinSupportedTargetSdkVersion(),
+ "ro.build.version.base_os=" + ctx.Config().PlatformBaseOS(),
+ "ro.build.tags=robolectric",
+ "ro.build.fingerprint=robolectric",
+ "ro.build.characteristics=robolectric",
+ "",
+ "# for backwards-compatibility reasons, set CPUs to unknown/ARM",
+ "ro.product.cpu.abi=unknown",
+ "ro.product.cpu.abi2=unknown",
+ "ro.product.cpu.abilist=armeabi-v7a",
+ "ro.product.cpu.abilist32=armeabi-v7a,armeabi",
+ "ro.product.cpu.abilist64=armeabi-v7a,armeabi",
+ "",
+ "# temp fix for robolectric freezing issue b/150011638",
+ "persist.debug.new_insets=0",
+ }
+
+ b.output = android.PathForModuleGen(ctx, "build.prop")
+
+ rule := android.NewRuleBuilder(pctx, ctx)
+
+ rule.Command().Text("rm").Flag("-f").Output(b.output)
+ for _, l := range lines {
+ rule.Command().Text("echo").Text("'" + l + "'").Text(">>").Output(b.output)
+ }
+
+ rule.Build("build_prop", "robolectric build.prop")
+}
+
+func buildPropsFactory() android.Module {
+ module := &buildProps{}
+ android.InitAndroidModule(module)
+ return module
+}
diff --git a/testapp/Android.bp b/testapp/Android.bp
index a11ba44f2..a8c52b815 100644
--- a/testapp/Android.bp
+++ b/testapp/Android.bp
@@ -11,7 +11,10 @@ android_library {
platform_apis: true,
manifest: "src/main/AndroidManifest.xml",
optimize: {
- enabled: false
+ enabled: false,
+ },
+ lint: {
+ baseline_filename: "lint-baseline.xml",
},
}
@@ -38,4 +41,7 @@ android_app {
kotlincflags: ["-Xjvm-default=all"],
plugins: ["dagger2-compiler"],
+ lint: {
+ baseline_filename: "lint-baseline.xml",
+ },
}
diff --git a/testapp/lint-baseline.xml b/testapp/lint-baseline.xml
new file mode 100644
index 000000000..957e3d023
--- /dev/null
+++ b/testapp/lint-baseline.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01">
+
+ <issue
+ id="NewApi"
+ message="`&lt;vector&gt;` requires API level 21 (current min is 16) or building with Android Gradle plugin 1.4.0 or higher"
+ errorLine1='&lt;vector xmlns:android="http://schemas.android.com/apk/res/android"'
+ errorLine2=" ~~~~~~">
+ <location
+ file="external/robolectric/testapp/src/main/res/drawable-anydpi/an_image_or_vector.xml"
+ line="2"
+ column="2"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="`&lt;vector&gt;` requires API level 21 (current min is 16) or building with Android Gradle plugin 1.4.0 or higher"
+ errorLine1='&lt;vector xmlns:android="http://schemas.android.com/apk/res/android"'
+ errorLine2=" ~~~~~~">
+ <location
+ file="external/robolectric/testapp/src/main/res/drawable/vector.xml"
+ line="1"
+ column="2"/>
+ </issue>
+
+</issues> \ No newline at end of file