summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp17
-rw-r--r--core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java66
-rw-r--r--core/java/android/content/pm/PackageBackwardCompatibility.java154
-rw-r--r--core/java/android/content/pm/PackageSharedLibraryUpdater.java55
-rw-r--r--core/tests/coretests/Android.mk4
-rw-r--r--core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java66
6 files changed, 300 insertions, 62 deletions
diff --git a/Android.bp b/Android.bp
index 9e9faf2d7ffa..c775d15f6bb2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -630,6 +630,11 @@ java_library {
],
},
+ // See comment on framework-oahl-backward-compatibility module below
+ exclude_srcs: [
+ "core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java",
+ ],
+
no_framework_libs: true,
libs: [
"conscrypt",
@@ -665,6 +670,18 @@ java_library {
],
}
+// A temporary build target that is conditionally included on the bootclasspath if
+// org.apache.http.legacy library has been removed and which provides support for
+// maintaining backwards compatibility for APKs that target pre-P and depend on
+// org.apache.http.legacy classes. This is used iff REMOVE_OAHL_FROM_BCP=true is
+// specified on the build command line.
+java_library {
+ name: "framework-oahl-backward-compatibility",
+ srcs: [
+ "core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java",
+ ],
+}
+
genrule {
name: "framework-statslog-gen",
tools: ["stats-log-api-gen"],
diff --git a/core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java b/core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java
new file mode 100644
index 000000000000..81041e9d3ba6
--- /dev/null
+++ b/core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java
@@ -0,0 +1,66 @@
+/*
+ * 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 android.content.pm.PackageParser.Package;
+import android.os.Build;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+
+/**
+ * Updates a package to ensure that if it targets < P that the org.apache.http.legacy library is
+ * included by default.
+ *
+ * <p>This is separated out so that it can be conditionally included at build time depending on
+ * whether org.apache.http.legacy is on the bootclasspath or not. In order to include this at
+ * build time, and remove org.apache.http.legacy from the bootclasspath pass
+ * REMOVE_OAHL_FROM_BCP=true on the build command line, otherwise this class will not be included
+ * and the
+ *
+ * @hide
+ */
+@VisibleForTesting
+public class OrgApacheHttpLegacyUpdater extends PackageSharedLibraryUpdater {
+
+ private static final String APACHE_HTTP_LEGACY = "org.apache.http.legacy";
+
+ @Override
+ public void updatePackage(Package pkg) {
+ ArrayList<String> usesLibraries = pkg.usesLibraries;
+ ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries;
+
+ // Packages targeted at <= O_MR1 expect the classes in the org.apache.http.legacy library
+ // to be accessible so this maintains backward compatibility by adding the
+ // org.apache.http.legacy library to those packages.
+ if (apkTargetsApiLevelLessThanOrEqualToOMR1(pkg)) {
+ boolean apacheHttpLegacyPresent = isLibraryPresent(
+ usesLibraries, usesOptionalLibraries, APACHE_HTTP_LEGACY);
+ if (!apacheHttpLegacyPresent) {
+ usesLibraries = prefix(usesLibraries, APACHE_HTTP_LEGACY);
+ }
+ }
+
+ pkg.usesLibraries = usesLibraries;
+ pkg.usesOptionalLibraries = usesOptionalLibraries;
+ }
+
+ private static boolean apkTargetsApiLevelLessThanOrEqualToOMR1(Package pkg) {
+ int targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
+ return targetSdkVersion <= Build.VERSION_CODES.O_MR1;
+ }
+}
diff --git a/core/java/android/content/pm/PackageBackwardCompatibility.java b/core/java/android/content/pm/PackageBackwardCompatibility.java
index 8014c94d198d..9bdb78be5442 100644
--- a/core/java/android/content/pm/PackageBackwardCompatibility.java
+++ b/core/java/android/content/pm/PackageBackwardCompatibility.java
@@ -16,15 +16,14 @@
package android.content.pm;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.content.pm.PackageParser.Package;
-import android.os.Build;
+import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import java.util.ArrayList;
+import java.util.List;
/**
* Modifies {@link Package} in order to maintain backwards compatibility.
@@ -32,13 +31,60 @@ import java.util.ArrayList;
* @hide
*/
@VisibleForTesting
-public class PackageBackwardCompatibility {
+public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater {
+
+ private static final String TAG = PackageBackwardCompatibility.class.getSimpleName();
private static final String ANDROID_TEST_MOCK = "android.test.mock";
private static final String ANDROID_TEST_RUNNER = "android.test.runner";
- private static final String APACHE_HTTP_LEGACY = "org.apache.http.legacy";
+ private static final PackageBackwardCompatibility INSTANCE;
+
+ static {
+ String className = "android.content.pm.OrgApacheHttpLegacyUpdater";
+ Class<? extends PackageSharedLibraryUpdater> clazz;
+ try {
+ clazz = (PackageBackwardCompatibility.class.getClassLoader()
+ .loadClass(className)
+ .asSubclass(PackageSharedLibraryUpdater.class));
+ } catch (ClassNotFoundException e) {
+ Log.i(TAG, "Could not find " + className + ", ignoring");
+ clazz = null;
+ }
+
+ boolean hasOrgApacheHttpLegacy = false;
+ final List<PackageSharedLibraryUpdater> packageUpdaters = new ArrayList<>();
+ if (clazz == null) {
+ // Add an 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.
+ packageUpdaters.add(new RemoveUnnecessaryOrgApacheHttpLegacyLibrary());
+ } else {
+ try {
+ packageUpdaters.add(clazz.getConstructor().newInstance());
+ hasOrgApacheHttpLegacy = true;
+ } catch (ReflectiveOperationException e) {
+ throw new IllegalStateException("Could not create instance of " + className, e);
+ }
+ }
+
+ packageUpdaters.add(new AndroidTestRunnerSplitUpdater());
+
+ PackageSharedLibraryUpdater[] updaterArray = packageUpdaters
+ .toArray(new PackageSharedLibraryUpdater[0]);
+ INSTANCE = new PackageBackwardCompatibility(hasOrgApacheHttpLegacy, updaterArray);
+ }
+
+ private final boolean mRemovedOAHLFromBCP;
+
+ private final PackageSharedLibraryUpdater[] mPackageUpdaters;
+
+ public PackageBackwardCompatibility(boolean removedOAHLFromBCP,
+ PackageSharedLibraryUpdater[] packageUpdaters) {
+ this.mRemovedOAHLFromBCP = removedOAHLFromBCP;
+ this.mPackageUpdaters = packageUpdaters;
+ }
/**
* Modify the shared libraries in the supplied {@link Package} to maintain backwards
@@ -48,52 +94,74 @@ public class PackageBackwardCompatibility {
*/
@VisibleForTesting
public static void modifySharedLibraries(Package pkg) {
- ArrayList<String> usesLibraries = pkg.usesLibraries;
- ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries;
-
- // Packages targeted at <= O_MR1 expect the classes in the org.apache.http.legacy library
- // to be accessible so this maintains backward compatibility by adding the
- // org.apache.http.legacy library to those packages.
- if (apkTargetsApiLevelLessThanOrEqualToOMR1(pkg)) {
- boolean apacheHttpLegacyPresent = isLibraryPresent(
- usesLibraries, usesOptionalLibraries, APACHE_HTTP_LEGACY);
- if (!apacheHttpLegacyPresent) {
- usesLibraries = prefix(usesLibraries, APACHE_HTTP_LEGACY);
- }
- }
+ INSTANCE.updatePackage(pkg);
+ }
- // android.test.runner has a dependency on android.test.mock so if android.test.runner
- // is present but android.test.mock is not then add android.test.mock.
- boolean androidTestMockPresent = isLibraryPresent(
- usesLibraries, usesOptionalLibraries, ANDROID_TEST_MOCK);
- if (ArrayUtils.contains(usesLibraries, ANDROID_TEST_RUNNER) && !androidTestMockPresent) {
- usesLibraries.add(ANDROID_TEST_MOCK);
- }
- if (ArrayUtils.contains(usesOptionalLibraries, ANDROID_TEST_RUNNER)
- && !androidTestMockPresent) {
- usesOptionalLibraries.add(ANDROID_TEST_MOCK);
- }
+ @Override
+ public void updatePackage(Package pkg) {
- pkg.usesLibraries = usesLibraries;
- pkg.usesOptionalLibraries = usesOptionalLibraries;
+ for (PackageSharedLibraryUpdater packageUpdater : mPackageUpdaters) {
+ packageUpdater.updatePackage(pkg);
+ }
}
- private static boolean apkTargetsApiLevelLessThanOrEqualToOMR1(Package pkg) {
- int targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
- return targetSdkVersion <= Build.VERSION_CODES.O_MR1;
+ /**
+ * True if the org.apache.http.legacy has been removed the bootclasspath, false otherwise.
+ */
+ public static boolean removeOAHLFromBCP() {
+ return INSTANCE.mRemovedOAHLFromBCP;
}
- private static boolean isLibraryPresent(ArrayList<String> usesLibraries,
- ArrayList<String> usesOptionalLibraries, String apacheHttpLegacy) {
- return ArrayUtils.contains(usesLibraries, apacheHttpLegacy)
- || ArrayUtils.contains(usesOptionalLibraries, apacheHttpLegacy);
+ /**
+ * Add android.test.mock dependency for any APK that depends on android.test.runner.
+ *
+ * <p>This is needed to maintain backwards compatibility as in previous versions of Android the
+ * android.test.runner library included the classes from android.test.mock which have since
+ * been split out into a separate library.
+ *
+ * @hide
+ */
+ @VisibleForTesting
+ public static class AndroidTestRunnerSplitUpdater extends PackageSharedLibraryUpdater {
+
+ @Override
+ public void updatePackage(Package pkg) {
+ ArrayList<String> usesLibraries = pkg.usesLibraries;
+ ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries;
+
+ // android.test.runner has a dependency on android.test.mock so if android.test.runner
+ // is present but android.test.mock is not then add android.test.mock.
+ boolean androidTestMockPresent = isLibraryPresent(
+ usesLibraries, usesOptionalLibraries, ANDROID_TEST_MOCK);
+ if (ArrayUtils.contains(usesLibraries, ANDROID_TEST_RUNNER)
+ && !androidTestMockPresent) {
+ usesLibraries.add(ANDROID_TEST_MOCK);
+ }
+ if (ArrayUtils.contains(usesOptionalLibraries, ANDROID_TEST_RUNNER)
+ && !androidTestMockPresent) {
+ usesOptionalLibraries.add(ANDROID_TEST_MOCK);
+ }
+
+ pkg.usesLibraries = usesLibraries;
+ pkg.usesOptionalLibraries = usesOptionalLibraries;
+ }
}
- private static @NonNull <T> ArrayList<T> prefix(@Nullable ArrayList<T> cur, T val) {
- if (cur == null) {
- cur = new ArrayList<>();
+ /**
+ * Remove any usages of org.apache.http.legacy from the shared library as the library is on the
+ * bootclasspath.
+ */
+ @VisibleForTesting
+ public static class RemoveUnnecessaryOrgApacheHttpLegacyLibrary
+ extends PackageSharedLibraryUpdater {
+
+ private static final String APACHE_HTTP_LEGACY = "org.apache.http.legacy";
+
+ @Override
+ public void updatePackage(Package pkg) {
+ pkg.usesLibraries = ArrayUtils.remove(pkg.usesLibraries, APACHE_HTTP_LEGACY);
+ pkg.usesOptionalLibraries =
+ ArrayUtils.remove(pkg.usesOptionalLibraries, APACHE_HTTP_LEGACY);
}
- cur.add(0, val);
- return cur;
}
}
diff --git a/core/java/android/content/pm/PackageSharedLibraryUpdater.java b/core/java/android/content/pm/PackageSharedLibraryUpdater.java
new file mode 100644
index 000000000000..49d884ca2f34
--- /dev/null
+++ b/core/java/android/content/pm/PackageSharedLibraryUpdater.java
@@ -0,0 +1,55 @@
+/*
+ * 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 android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+
+import java.util.ArrayList;
+
+/**
+ * Base for classes that update a {@link PackageParser.Package}'s shared libraries.
+ *
+ * @hide
+ */
+@VisibleForTesting
+public abstract class PackageSharedLibraryUpdater {
+
+ /**
+ * Update the package's shared libraries.
+ *
+ * @param pkg the package to update.
+ */
+ public abstract void updatePackage(PackageParser.Package pkg);
+
+ static @NonNull
+ <T> ArrayList<T> prefix(@Nullable ArrayList<T> cur, T val) {
+ if (cur == null) {
+ cur = new ArrayList<>();
+ }
+ cur.add(0, val);
+ return cur;
+ }
+
+ static boolean isLibraryPresent(ArrayList<String> usesLibraries,
+ ArrayList<String> usesOptionalLibraries, String apacheHttpLegacy) {
+ return ArrayUtils.contains(usesLibraries, apacheHttpLegacy)
+ || ArrayUtils.contains(usesOptionalLibraries, apacheHttpLegacy);
+ }
+}
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index 47990a168ab3..60b46b453100 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -53,6 +53,10 @@ LOCAL_JAVA_LIBRARIES := \
android.test.base \
android.test.mock \
+ifeq ($(REMOVE_OAHL_FROM_BCP),true)
+LOCAL_JAVA_LIBRARIES += framework-oahl-backward-compatibility
+endif
+
LOCAL_PACKAGE_NAME := FrameworksCoreTests
LOCAL_COMPATIBILITY_SUITE := device-tests
diff --git a/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java b/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java
index 63a5e4cc1dd8..6996e5056466 100644
--- a/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java
+++ b/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java
@@ -73,9 +73,13 @@ public class PackageBackwardCompatibilityTest {
public void targeted_at_O() {
mPackage.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
PackageBackwardCompatibility.modifySharedLibraries(mPackage);
- assertEquals("usesLibraries not updated correctly",
- arrayList(ORG_APACHE_HTTP_LEGACY),
- mPackage.usesLibraries);
+ if (PackageBackwardCompatibility.removeOAHLFromBCP()) {
+ assertEquals("usesLibraries not updated correctly",
+ arrayList(ORG_APACHE_HTTP_LEGACY),
+ mPackage.usesLibraries);
+ } else {
+ assertNull("usesOptionalLibraries not updated correctly", mPackage.usesLibraries);
+ }
assertNull("usesOptionalLibraries not updated correctly", mPackage.usesOptionalLibraries);
}
@@ -84,10 +88,16 @@ public class PackageBackwardCompatibilityTest {
mPackage.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
mPackage.usesLibraries = arrayList(OTHER_LIBRARY);
PackageBackwardCompatibility.modifySharedLibraries(mPackage);
- // The org.apache.http.legacy jar should be added at the start of the list.
- assertEquals("usesLibraries not updated correctly",
- arrayList(ORG_APACHE_HTTP_LEGACY, OTHER_LIBRARY),
- mPackage.usesLibraries);
+ if (PackageBackwardCompatibility.removeOAHLFromBCP()) {
+ // The org.apache.http.legacy jar should be added at the start of the list.
+ assertEquals("usesLibraries not updated correctly",
+ arrayList(ORG_APACHE_HTTP_LEGACY, OTHER_LIBRARY),
+ mPackage.usesLibraries);
+ } else {
+ assertEquals("usesLibraries not updated correctly",
+ arrayList(OTHER_LIBRARY),
+ mPackage.usesLibraries);
+ }
assertNull("usesOptionalLibraries not updated correctly", mPackage.usesOptionalLibraries);
}
@@ -96,9 +106,13 @@ public class PackageBackwardCompatibilityTest {
mPackage.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
mPackage.usesLibraries = arrayList(ORG_APACHE_HTTP_LEGACY);
PackageBackwardCompatibility.modifySharedLibraries(mPackage);
- assertEquals("usesLibraries not updated correctly",
- arrayList(ORG_APACHE_HTTP_LEGACY),
- mPackage.usesLibraries);
+ if (PackageBackwardCompatibility.removeOAHLFromBCP()) {
+ assertEquals("usesLibraries not updated correctly",
+ arrayList(ORG_APACHE_HTTP_LEGACY),
+ mPackage.usesLibraries);
+ } else {
+ assertNull("usesLibraries not updated correctly", mPackage.usesLibraries);
+ }
assertNull("usesOptionalLibraries not updated correctly", mPackage.usesOptionalLibraries);
}
@@ -108,18 +122,27 @@ public class PackageBackwardCompatibilityTest {
mPackage.usesOptionalLibraries = arrayList(ORG_APACHE_HTTP_LEGACY);
PackageBackwardCompatibility.modifySharedLibraries(mPackage);
assertNull("usesLibraries not updated correctly", mPackage.usesLibraries);
- assertEquals("usesOptionalLibraries not updated correctly",
- arrayList(ORG_APACHE_HTTP_LEGACY),
- mPackage.usesOptionalLibraries);
+ if (PackageBackwardCompatibility.removeOAHLFromBCP()) {
+ assertEquals("usesOptionalLibraries not updated correctly",
+ arrayList(ORG_APACHE_HTTP_LEGACY),
+ mPackage.usesOptionalLibraries);
+ } else {
+ assertNull("usesOptionalLibraries not updated correctly",
+ mPackage.usesOptionalLibraries);
+ }
}
@Test
public void org_apache_http_legacy_in_usesLibraries() {
mPackage.usesLibraries = arrayList(ORG_APACHE_HTTP_LEGACY);
PackageBackwardCompatibility.modifySharedLibraries(mPackage);
- assertEquals("usesLibraries not updated correctly",
- arrayList(ORG_APACHE_HTTP_LEGACY),
- mPackage.usesLibraries);
+ if (PackageBackwardCompatibility.removeOAHLFromBCP()) {
+ assertEquals("usesLibraries not updated correctly",
+ arrayList(ORG_APACHE_HTTP_LEGACY),
+ mPackage.usesLibraries);
+ } else {
+ assertNull("usesLibraries not updated correctly", mPackage.usesLibraries);
+ }
assertNull("usesOptionalLibraries not updated correctly", mPackage.usesOptionalLibraries);
}
@@ -128,9 +151,14 @@ public class PackageBackwardCompatibilityTest {
mPackage.usesOptionalLibraries = arrayList(ORG_APACHE_HTTP_LEGACY);
PackageBackwardCompatibility.modifySharedLibraries(mPackage);
assertNull("usesLibraries not updated correctly", mPackage.usesLibraries);
- assertEquals("usesOptionalLibraries not updated correctly",
- arrayList(ORG_APACHE_HTTP_LEGACY),
- mPackage.usesOptionalLibraries);
+ if (PackageBackwardCompatibility.removeOAHLFromBCP()) {
+ assertEquals("usesOptionalLibraries not updated correctly",
+ arrayList(ORG_APACHE_HTTP_LEGACY),
+ mPackage.usesOptionalLibraries);
+ } else {
+ assertNull("usesOptionalLibraries not updated correctly",
+ mPackage.usesOptionalLibraries);
+ }
}
@Test