diff options
| author | Pedro Loureiro <pedroql@google.com> | 2021-07-30 17:27:00 +0000 |
|---|---|---|
| committer | Pedro Loureiro <pedroql@google.com> | 2021-09-29 09:47:15 +0000 |
| commit | 70da334f7b8797c9d7b358b62dcfca8e463def48 (patch) | |
| tree | f75481faafcf282c04a90b9bb5f7b115f24057c6 /core/java | |
| parent | 6f7539ec0c66921753f9981f40a2e49b0a9434fc (diff) | |
Parse new xml attributes used for updatable shared libraries
Attributes added to the `library` tag used in AndroidManifest.xml.
They allow to easily and transparently include/exclude a library from
apps for compatibility purposes.
Bug: 191978330
Test: atest com.android.server.pm.parsing.library.ApexSharedLibraryUpdaterTest com.android.server.systemconfig.SystemConfigTest
Change-Id: Ibdde742a05fd670a9aaee5ee77ae25b9c0801f53
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/com/android/server/SystemConfig.java | 87 |
1 files changed, 80 insertions, 7 deletions
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index d7eef0d455b4..ec3dfad2ec2e 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -108,17 +108,74 @@ public class SystemConfig { public final String name; public final String filename; public final String[] dependencies; + + /** + * SDK version this library was added to the BOOTCLASSPATH. + * + * <p>At the SDK level specified in this field and higher, the apps' uses-library tags for + * this library will be ignored, since the library is always available on BOOTCLASSPATH. + * + * <p>0 means not specified. + */ + public final int onBootclasspathSince; + + /** + * SDK version this library was removed from the BOOTCLASSPATH. + * + * <p>At the SDK level specified in this field and higher, this library needs to be + * explicitly added by apps. For compatibility reasons, when an app + * targets an SDK less than the value of this attribute, this library is automatically + * added. + * + * <p>0 means not specified. + */ + public final int onBootclasspathBefore; + + /** + * Declares whether this library can be safely ignored from <uses-library> tags. + * + * <p> This can happen if the library initially had to be explicitly depended-on using that + * tag but has since been moved to the BOOTCLASSPATH which means now is always available + * and the tag is no longer required. + */ + public final boolean canBeSafelyIgnored; + public final boolean isNative; - SharedLibraryEntry(String name, String filename, String[] dependencies) { - this(name, filename, dependencies, false /* isNative */); + + @VisibleForTesting + public SharedLibraryEntry(String name, String filename, String[] dependencies, + boolean isNative) { + this(name, filename, dependencies, 0 /* onBootclasspathSince */, + 0 /* onBootclasspathBefore */, isNative); + } + + @VisibleForTesting + public SharedLibraryEntry(String name, String filename, String[] dependencies, + int onBootclasspathSince, int onBootclassPathBefore) { + this(name, filename, dependencies, onBootclasspathSince, onBootclassPathBefore, + false /* isNative */); } - SharedLibraryEntry(String name, String filename, String[] dependencies, boolean isNative) { + SharedLibraryEntry(String name, String filename, String[] dependencies, + int onBootclasspathSince, int onBootclasspathBefore, boolean isNative) { this.name = name; this.filename = filename; this.dependencies = dependencies; + this.onBootclasspathSince = onBootclasspathSince; + this.onBootclasspathBefore = onBootclasspathBefore; this.isNative = isNative; + + canBeSafelyIgnored = this.onBootclasspathSince != 0 + && isSdkAtLeast(this.onBootclasspathSince); + } + + private static boolean isSdkAtLeast(int level) { + if ("REL".equals(Build.VERSION.CODENAME)) { + return Build.VERSION.SDK_INT >= level; + } + return level == Build.VERSION_CODES.CUR_DEVELOPMENT + || Build.VERSION.SDK_INT >= level; } } @@ -771,11 +828,17 @@ public class SystemConfig { XmlUtils.skipCurrentTag(parser); } } break; + case "updatable-library": + // "updatable-library" is meant to behave exactly like "library" case "library": { if (allowLibs) { String lname = parser.getAttributeValue(null, "name"); String lfile = parser.getAttributeValue(null, "file"); String ldependency = parser.getAttributeValue(null, "dependency"); + int minDeviceSdk = XmlUtils.readIntAttribute(parser, "min-device-sdk", + 0); + int maxDeviceSdk = XmlUtils.readIntAttribute(parser, "max-device-sdk", + 0); if (lname == null) { Slog.w(TAG, "<" + name + "> without name in " + permFile + " at " + parser.getPositionDescription()); @@ -783,10 +846,20 @@ public class SystemConfig { Slog.w(TAG, "<" + name + "> without file in " + permFile + " at " + parser.getPositionDescription()); } else { - //Log.i(TAG, "Got library " + lname + " in " + lfile); - SharedLibraryEntry entry = new SharedLibraryEntry(lname, lfile, - ldependency == null ? new String[0] : ldependency.split(":")); - mSharedLibraries.put(lname, entry); + boolean allowedMinSdk = minDeviceSdk <= Build.VERSION.SDK_INT; + boolean allowedMaxSdk = + maxDeviceSdk == 0 || maxDeviceSdk >= Build.VERSION.SDK_INT; + if (allowedMinSdk && allowedMaxSdk) { + int bcpSince = XmlUtils.readIntAttribute(parser, + "on-bootclasspath-since", 0); + int bcpBefore = XmlUtils.readIntAttribute(parser, + "on-bootclasspath-before", 0); + SharedLibraryEntry entry = new SharedLibraryEntry(lname, lfile, + ldependency == null + ? new String[0] : ldependency.split(":"), + bcpSince, bcpBefore); + mSharedLibraries.put(lname, entry); + } } } else { logNotAllowedInPartition(name, permFile, parser); |
