diff --git a/Android.bp b/Android.bp index 28e51e733895..26e3b9145464 100644 --- a/Android.bp +++ b/Android.bp @@ -645,8 +645,10 @@ java_library { ], }, - // See comment on framework-oahl-backward-compatibility module below exclude_srcs: [ + // See comment on framework-atb-backward-compatibility module below + "core/java/android/content/pm/AndroidTestBaseUpdater.java", + // See comment on framework-oahl-backward-compatibility module below "core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java", ], @@ -699,6 +701,18 @@ java_library { ], } +// A temporary build target that is conditionally included on the bootclasspath if +// android.test.base library has been removed and which provides support for +// maintaining backwards compatibility for APKs that target pre-P and depend on +// android.test.base classes. This is used iff REMOVE_ATB_FROM_BCP=true is +// specified on the build command line. +java_library { + name: "framework-atb-backward-compatibility", + srcs: [ + "core/java/android/content/pm/AndroidTestBaseUpdater.java", + ], +} + genrule { name: "framework-statslog-gen", tools: ["stats-log-api-gen"], diff --git a/core/java/android/content/pm/AndroidTestBaseUpdater.java b/core/java/android/content/pm/AndroidTestBaseUpdater.java new file mode 100644 index 000000000000..2aaac0280a0e --- /dev/null +++ b/core/java/android/content/pm/AndroidTestBaseUpdater.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.content.pm; + +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER; + +import android.content.pm.PackageParser.Package; + +import com.android.internal.annotations.VisibleForTesting; + +/** + * Updates a package to ensure that if it targets < P that the android.test.base library is + * included by default. + * + *
This is separated out so that it can be conditionally included at build time depending on + * whether android.test.base is on the bootclasspath or not. In order to include this at + * build time, and remove android.test.base from the bootclasspath pass + * REMOVE_ATB_FROM_BCP=true on the build command line, otherwise this class will not be included + * and the + * + * @hide + */ +@VisibleForTesting +public class AndroidTestBaseUpdater extends PackageSharedLibraryUpdater { + + @Override + public void updatePackage(Package pkg) { + // Packages targeted at <= O_MR1 expect the classes in the android.test.base library + // to be accessible so this maintains backward compatibility by adding the + // android.test.base library to those packages. + if (apkTargetsApiLevelLessThanOrEqualToOMR1(pkg)) { + prefixRequiredLibrary(pkg, ANDROID_TEST_BASE); + } else { + // If a package already depends on android.test.runner then add a dependency on + // android.test.base because android.test.runner depends on classes from the + // android.test.base library. + prefixImplicitDependency(pkg, ANDROID_TEST_RUNNER, ANDROID_TEST_BASE); + } + } +} diff --git a/core/java/android/content/pm/PackageBackwardCompatibility.java b/core/java/android/content/pm/PackageBackwardCompatibility.java index 67e4cd561361..a16f81b11ae6 100644 --- a/core/java/android/content/pm/PackageBackwardCompatibility.java +++ b/core/java/android/content/pm/PackageBackwardCompatibility.java @@ -16,6 +16,7 @@ package android.content.pm; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE; import static android.content.pm.SharedLibraryNames.ANDROID_TEST_MOCK; import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER; import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; @@ -52,12 +53,22 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { "android.content.pm.OrgApacheHttpLegacyUpdater", RemoveUnnecessaryOrgApacheHttpLegacyLibrary::new); + // Add this before adding AndroidTestBaseUpdater so that android.test.base comes before + // android.test.mock. packageUpdaters.add(new AndroidTestRunnerSplitUpdater()); + // Attempt to load and add the optional updater that will only be available when + // REMOVE_ATB_FROM_BCP=true. If that could not be found then add the default updater that + // will remove any references to org.apache.http.library from the package so that it does + // not try and load the library when it is on the bootclasspath. + boolean bootClassPathContainsATB = !addOptionalUpdater(packageUpdaters, + "android.content.pm.AndroidTestBaseUpdater", + RemoveUnnecessaryAndroidTestBaseLibrary::new); + PackageSharedLibraryUpdater[] updaterArray = packageUpdaters .toArray(new PackageSharedLibraryUpdater[0]); INSTANCE = new PackageBackwardCompatibility( - bootClassPathContainsOAHL, updaterArray); + bootClassPathContainsOAHL, bootClassPathContainsATB, updaterArray); } /** @@ -105,11 +116,14 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { private final boolean mBootClassPathContainsOAHL; + private final boolean mBootClassPathContainsATB; + private final PackageSharedLibraryUpdater[] mPackageUpdaters; public PackageBackwardCompatibility(boolean bootClassPathContainsOAHL, - PackageSharedLibraryUpdater[] packageUpdaters) { + boolean bootClassPathContainsATB, PackageSharedLibraryUpdater[] packageUpdaters) { this.mBootClassPathContainsOAHL = bootClassPathContainsOAHL; + this.mBootClassPathContainsATB = bootClassPathContainsATB; this.mPackageUpdaters = packageUpdaters; } @@ -139,6 +153,14 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { return INSTANCE.mBootClassPathContainsOAHL; } + /** + * True if the android.test.base is on the bootclasspath, false otherwise. + */ + @VisibleForTesting + public static boolean bootClassPathContainsATB() { + return INSTANCE.mBootClassPathContainsATB; + } + /** * Add android.test.mock dependency for any APK that depends on android.test.runner. * @@ -173,4 +195,18 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { } } + + /** + * Remove any usages of android.test.base from the shared library as the library is on the + * bootclasspath. + */ + @VisibleForTesting + public static class RemoveUnnecessaryAndroidTestBaseLibrary + extends PackageSharedLibraryUpdater { + + @Override + public void updatePackage(Package pkg) { + removeLibrary(pkg, ANDROID_TEST_BASE); + } + } } diff --git a/core/java/android/content/pm/SharedLibraryNames.java b/core/java/android/content/pm/SharedLibraryNames.java index 3fbf664b1a83..83e86636424a 100644 --- a/core/java/android/content/pm/SharedLibraryNames.java +++ b/core/java/android/content/pm/SharedLibraryNames.java @@ -22,6 +22,8 @@ package android.content.pm; */ public class SharedLibraryNames { + static final String ANDROID_TEST_BASE = "android.test.base"; + static final String ANDROID_TEST_MOCK = "android.test.mock"; static final String ANDROID_TEST_RUNNER = "android.test.runner"; diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk index 66731df3f1b9..2ea1b46ad208 100644 --- a/core/tests/coretests/Android.mk +++ b/core/tests/coretests/Android.mk @@ -53,6 +53,7 @@ LOCAL_JAVA_LIBRARIES := \ android.test.base \ android.test.mock \ framework-oahl-backward-compatibility \ + framework-atb-backward-compatibility \ LOCAL_PACKAGE_NAME := FrameworksCoreTests LOCAL_COMPATIBILITY_SUITE := device-tests diff --git a/core/tests/coretests/src/android/content/pm/AndroidTestBaseUpdaterTest.java b/core/tests/coretests/src/android/content/pm/AndroidTestBaseUpdaterTest.java new file mode 100644 index 000000000000..dce22ce6a6f2 --- /dev/null +++ b/core/tests/coretests/src/android/content/pm/AndroidTestBaseUpdaterTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.content.pm; + +import static android.content.pm.PackageBuilder.builder; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE; + +import android.os.Build; +import android.support.test.filters.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Test for {@link AndroidTestBaseUpdater} + */ +@SmallTest +@RunWith(OptionalClassRunner.class) +@OptionalClassRunner.OptionalClass("android.content.pm.AndroidTestBaseUpdater") +public class AndroidTestBaseUpdaterTest extends PackageSharedLibraryUpdaterTest { + + private static final String OTHER_LIBRARY = "other.library"; + + @Test + public void targeted_at_O() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O); + + // Should add org.apache.http.legacy. + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(ANDROID_TEST_BASE); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_O_not_empty_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(OTHER_LIBRARY); + + // The org.apache.http.legacy jar should be added at the start of the list because it + // is not on the bootclasspath and the package targets pre-P. + PackageBuilder after = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(ANDROID_TEST_BASE, OTHER_LIBRARY); + + checkBackwardsCompatibility(before, after); + } + + @Test + public void targeted_at_O_in_usesLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .requiredLibraries(ANDROID_TEST_BASE); + + // No change is required because although org.apache.http.legacy has been removed from + // the bootclasspath the package explicitly requests it. + checkBackwardsCompatibility(before, before); + } + + @Test + public void targeted_at_O_in_usesOptionalLibraries() { + PackageBuilder before = builder() + .targetSdkVersion(Build.VERSION_CODES.O) + .optionalLibraries(ANDROID_TEST_BASE); + + // No change is required because although org.apache.http.legacy has been removed from + // the bootclasspath the package explicitly requests it. + checkBackwardsCompatibility(before, before); + } + + @Test + public void in_usesLibraries() { + PackageBuilder before = builder().requiredLibraries(ANDROID_TEST_BASE); + + // No change is required because the package explicitly requests org.apache.http.legacy + // and is targeted at the current version so does not need backwards compatibility. + checkBackwardsCompatibility(before, before); + } + + @Test + public void in_usesOptionalLibraries() { + PackageBuilder before = builder().optionalLibraries(ANDROID_TEST_BASE); + + // No change is required because the package explicitly requests org.apache.http.legacy + // and is targeted at the current version so does not need backwards compatibility. + checkBackwardsCompatibility(before, before); + } + + private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) { + checkBackwardsCompatibility(before, after, AndroidTestBaseUpdater::new); + } +} diff --git a/core/tests/coretests/src/android/content/pm/AndroidTestRunnerSplitUpdaterTest.java b/core/tests/coretests/src/android/content/pm/AndroidTestRunnerSplitUpdaterTest.java index a305261890f4..866de93c07fe 100644 --- a/core/tests/coretests/src/android/content/pm/AndroidTestRunnerSplitUpdaterTest.java +++ b/core/tests/coretests/src/android/content/pm/AndroidTestRunnerSplitUpdaterTest.java @@ -38,7 +38,7 @@ public class AndroidTestRunnerSplitUpdaterTest extends PackageSharedLibraryUpdat PackageBuilder before = builder().optionalLibraries(ANDROID_TEST_RUNNER); PackageBuilder after = builder() - .optionalLibraries(ANDROID_TEST_RUNNER, ANDROID_TEST_MOCK); + .optionalLibraries(ANDROID_TEST_MOCK, ANDROID_TEST_RUNNER); checkBackwardsCompatibility(before, after); } diff --git a/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java b/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java index b26fc48d8d5b..c64d5202e1fd 100644 --- a/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java +++ b/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java @@ -17,10 +17,12 @@ package android.content.pm; import static android.content.pm.PackageBuilder.builder; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE; import static android.content.pm.SharedLibraryNames.ANDROID_TEST_MOCK; import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER; import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; +import android.content.pm.PackageBackwardCompatibility.RemoveUnnecessaryAndroidTestBaseLibrary; import android.os.Build; import android.support.test.filters.SmallTest; @@ -55,9 +57,20 @@ public class PackageBackwardCompatibilityTest extends PackageSharedLibraryUpdate Assume.assumeTrue(PackageBackwardCompatibility.bootClassPathContainsOAHL()); } + /** + * Detect when the android.test.base is not on the bootclasspath. + * + *
This test will be ignored when org.apache.http.legacy is not on the bootclasspath and + * succeed otherwise. This allows a developer to ensure that the tests are being + */ + @Test + public void detectWhenATBisOnBCP() { + Assume.assumeTrue(PackageBackwardCompatibility.bootClassPathContainsATB()); + } + /** * Ensures that the {@link PackageBackwardCompatibility} uses {@link OrgApacheHttpLegacyUpdater} - * when necessary. + * and {@link AndroidTestBaseUpdater} when necessary. * *
More comprehensive tests for that class can be found in
* {@link OrgApacheHttpLegacyUpdaterTest}.
@@ -68,6 +81,9 @@ public class PackageBackwardCompatibilityTest extends PackageSharedLibraryUpdate
.targetSdkVersion(Build.VERSION_CODES.O);
List More comprehensive tests for that class can be found in
+ * {@link RemoveUnnecessaryAndroidTestBaseLibraryTest}.
+ */
+ @Test
+ public void android_test_base_in_usesLibraries() {
+ Assume.assumeTrue("Test requires that "
+ + ANDROID_TEST_BASE + " is on the bootclasspath",
+ PackageBackwardCompatibility.bootClassPathContainsATB());
+
+ PackageBuilder before = builder()
+ .requiredLibraries(ANDROID_TEST_BASE);
+
+ // android.test.base should be removed from the libraries because it is provided
+ // on the bootclasspath and providing both increases start up cost unnecessarily.
+ PackageBuilder after = builder();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
/**
* Ensures that the {@link PackageBackwardCompatibility} uses a
* {@link PackageBackwardCompatibility.AndroidTestRunnerSplitUpdater}.
@@ -114,8 +154,15 @@ public class PackageBackwardCompatibilityTest extends PackageSharedLibraryUpdate
public void android_test_runner_in_usesLibraries() {
PackageBuilder before = builder().requiredLibraries(ANDROID_TEST_RUNNER);
+ List