diff options
34 files changed, 1062 insertions, 210 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index f5f3bb091f28..7949c803505a 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -13237,6 +13237,7 @@ package android.content.pm { field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.SharedLibraryInfo> CREATOR; field public static final int TYPE_BUILTIN = 0; // 0x0 field public static final int TYPE_DYNAMIC = 1; // 0x1 + field public static final int TYPE_SDK = 3; // 0x3 field public static final int TYPE_STATIC = 2; // 0x2 field public static final int VERSION_UNDEFINED = -1; // 0xffffffff } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index c777bf542706..a7f38016fb48 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -697,7 +697,7 @@ public abstract class PackageManager { MATCH_DISABLED_COMPONENTS, MATCH_DISABLED_UNTIL_USED_COMPONENTS, MATCH_INSTANT, - MATCH_STATIC_SHARED_LIBRARIES, + MATCH_STATIC_SHARED_AND_SDK_LIBRARIES, GET_DISABLED_UNTIL_USED_COMPONENTS, GET_UNINSTALLED_PACKAGES, MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, @@ -721,7 +721,7 @@ public abstract class PackageManager { MATCH_SYSTEM_ONLY, MATCH_UNINSTALLED_PACKAGES, MATCH_INSTANT, - MATCH_STATIC_SHARED_LIBRARIES, + MATCH_STATIC_SHARED_AND_SDK_LIBRARIES, GET_DISABLED_COMPONENTS, GET_DISABLED_UNTIL_USED_COMPONENTS, GET_UNINSTALLED_PACKAGES, @@ -1038,14 +1038,14 @@ public abstract class PackageManager { public static final int MATCH_EXPLICITLY_VISIBLE_ONLY = 0x02000000; /** - * Internal {@link PackageInfo} flag: include static shared libraries. - * Apps that depend on static shared libs can always access the version + * Internal {@link PackageInfo} flag: include static shared and SDK libraries. + * Apps that depend on static shared/SDK libs can always access the version * of the lib they depend on. System/shell/root can access all shared * libs regardless of dependency but need to explicitly ask for them * via this flag. * @hide */ - public static final int MATCH_STATIC_SHARED_LIBRARIES = 0x04000000; + public static final int MATCH_STATIC_SHARED_AND_SDK_LIBRARIES = 0x04000000; /** * {@link PackageInfo} flag: return the signing certificates associated with diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java index 7abb6947095f..4ba2ee65f221 100644 --- a/core/java/android/content/pm/SharedLibraryInfo.java +++ b/core/java/android/content/pm/SharedLibraryInfo.java @@ -70,6 +70,13 @@ public final class SharedLibraryInfo implements Parcelable { public static final int TYPE_STATIC = 2; /** + * SDK library type: this library is <strong>not</strong> backwards + * -compatible, can be updated and updates can be uninstalled. Clients + * depend on a specific version of the library. + */ + public static final int TYPE_SDK = 3; + + /** * Constant for referring to an undefined version. */ public static final int VERSION_UNDEFINED = -1; @@ -289,6 +296,13 @@ public final class SharedLibraryInfo implements Parcelable { } /** + * @hide + */ + public boolean isSdk() { + return mType == TYPE_SDK; + } + + /** * Gets the package that declares the library. * * @return The package declaring the library. @@ -351,6 +365,9 @@ public final class SharedLibraryInfo implements Parcelable { case TYPE_STATIC: { return "static"; } + case TYPE_SDK: { + return "sdk"; + } default: { return "unknown"; } diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java index 056f99fcc004..63332e79c88b 100644 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ b/core/java/android/content/pm/parsing/ParsingPackage.java @@ -103,11 +103,11 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage addUsesOptionalNativeLibrary(String libraryName); - ParsingPackage addUsesStaticLibrary(String libraryName); + ParsingPackage addUsesSdkLibrary(String libraryName, long versionMajor, + String[] certSha256Digests); - ParsingPackage addUsesStaticLibraryCertDigests(String[] certSha256Digests); - - ParsingPackage addUsesStaticLibraryVersion(long version); + ParsingPackage addUsesStaticLibrary(String libraryName, long version, + String[] certSha256Digests); ParsingPackage addQueriesIntent(Intent intent); @@ -212,6 +212,12 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage setRestoreAnyVersion(boolean restoreAnyVersion); + ParsingPackage setSdkLibName(String sdkLibName); + + ParsingPackage setSdkLibVersionMajor(int sdkLibVersionMajor); + + ParsingPackage setSdkLibrary(boolean sdkLibrary); + ParsingPackage setSplitHasCode(int splitIndex, boolean splitHasCode); ParsingPackage setStaticSharedLibrary(boolean staticSharedLibrary); diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index d5957a2b6924..19a8ce92373d 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -179,6 +179,10 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, @Nullable @DataClass.ParcelWith(ForInternedString.class) + private String sdkLibName; + private int sdkLibVersionMajor; + @Nullable + @DataClass.ParcelWith(ForInternedString.class) private String staticSharedLibName; private long staticSharedLibVersion; @NonNull @@ -203,10 +207,17 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, private List<String> usesStaticLibraries = emptyList(); @Nullable private long[] usesStaticLibrariesVersions; - @Nullable private String[][] usesStaticLibrariesCertDigests; + @NonNull + @DataClass.ParcelWith(ForInternedStringList.class) + private List<String> usesSdkLibraries = emptyList(); + @Nullable + private long[] usesSdkLibrariesVersionsMajor; + @Nullable + private String[][] usesSdkLibrariesCertDigests; + @Nullable @DataClass.ParcelWith(ForInternedString.class) private String sharedUserId; @@ -518,6 +529,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, private static final long REQUEST_FOREGROUND_SERVICE_EXEMPTION = 1L << 46; private static final long ATTRIBUTIONS_ARE_USER_VISIBLE = 1L << 47; private static final long RESET_ENABLED_SETTINGS_ON_APP_DATA_CLEARED = 1L << 48; + private static final long SDK_LIBRARY = 1L << 49; } private ParsingPackageImpl setBoolean(@Booleans.Values long flag, boolean value) { @@ -828,21 +840,24 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, } @Override - public ParsingPackageImpl addUsesStaticLibrary(String libraryName) { - this.usesStaticLibraries = CollectionUtils.add(this.usesStaticLibraries, + public ParsingPackageImpl addUsesSdkLibrary(String libraryName, long versionMajor, + String[] certSha256Digests) { + this.usesSdkLibraries = CollectionUtils.add(this.usesSdkLibraries, TextUtils.safeIntern(libraryName)); + this.usesSdkLibrariesVersionsMajor = ArrayUtils.appendLong( + this.usesSdkLibrariesVersionsMajor, versionMajor, true); + this.usesSdkLibrariesCertDigests = ArrayUtils.appendElement(String[].class, + this.usesSdkLibrariesCertDigests, certSha256Digests, true); return this; } @Override - public ParsingPackageImpl addUsesStaticLibraryVersion(long version) { + public ParsingPackageImpl addUsesStaticLibrary(String libraryName, long version, + String[] certSha256Digests) { + this.usesStaticLibraries = CollectionUtils.add(this.usesStaticLibraries, + TextUtils.safeIntern(libraryName)); this.usesStaticLibrariesVersions = ArrayUtils.appendLong(this.usesStaticLibrariesVersions, version, true); - return this; - } - - @Override - public ParsingPackageImpl addUsesStaticLibraryCertDigests(String[] certSha256Digests) { this.usesStaticLibrariesCertDigests = ArrayUtils.appendElement(String[].class, this.usesStaticLibrariesCertDigests, certSha256Digests, true); return this; @@ -1136,6 +1151,8 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, dest.writeString(this.overlayCategory); dest.writeInt(this.overlayPriority); sForInternedStringValueMap.parcel(this.overlayables, dest, flags); + sForInternedString.parcel(this.sdkLibName, dest, flags); + dest.writeInt(this.sdkLibVersionMajor); sForInternedString.parcel(this.staticSharedLibName, dest, flags); dest.writeLong(this.staticSharedLibVersion); sForInternedStringList.parcel(this.libraryNames, dest, flags); @@ -1143,9 +1160,9 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, sForInternedStringList.parcel(this.usesOptionalLibraries, dest, flags); sForInternedStringList.parcel(this.usesNativeLibraries, dest, flags); sForInternedStringList.parcel(this.usesOptionalNativeLibraries, dest, flags); + sForInternedStringList.parcel(this.usesStaticLibraries, dest, flags); dest.writeLongArray(this.usesStaticLibrariesVersions); - if (this.usesStaticLibrariesCertDigests == null) { dest.writeInt(-1); } else { @@ -1155,6 +1172,17 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, } } + sForInternedStringList.parcel(this.usesSdkLibraries, dest, flags); + dest.writeLongArray(this.usesSdkLibrariesVersionsMajor); + if (this.usesSdkLibrariesCertDigests == null) { + dest.writeInt(-1); + } else { + dest.writeInt(this.usesSdkLibrariesCertDigests.length); + for (int index = 0; index < this.usesSdkLibrariesCertDigests.length; index++) { + dest.writeStringArray(this.usesSdkLibrariesCertDigests[index]); + } + } + sForInternedString.parcel(this.sharedUserId, dest, flags); dest.writeInt(this.sharedUserLabel); dest.writeTypedList(this.configPreferences); @@ -1259,6 +1287,8 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, this.overlayCategory = in.readString(); this.overlayPriority = in.readInt(); this.overlayables = sForInternedStringValueMap.unparcel(in); + this.sdkLibName = sForInternedString.unparcel(in); + this.sdkLibVersionMajor = in.readInt(); this.staticSharedLibName = sForInternedString.unparcel(in); this.staticSharedLibVersion = in.readLong(); this.libraryNames = sForInternedStringList.unparcel(in); @@ -1266,14 +1296,29 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, this.usesOptionalLibraries = sForInternedStringList.unparcel(in); this.usesNativeLibraries = sForInternedStringList.unparcel(in); this.usesOptionalNativeLibraries = sForInternedStringList.unparcel(in); + this.usesStaticLibraries = sForInternedStringList.unparcel(in); this.usesStaticLibrariesVersions = in.createLongArray(); + { + int digestsSize = in.readInt(); + if (digestsSize >= 0) { + this.usesStaticLibrariesCertDigests = new String[digestsSize][]; + for (int index = 0; index < digestsSize; index++) { + this.usesStaticLibrariesCertDigests[index] = sForInternedStringArray.unparcel( + in); + } + } + } - int digestsSize = in.readInt(); - if (digestsSize >= 0) { - this.usesStaticLibrariesCertDigests = new String[digestsSize][]; - for (int index = 0; index < digestsSize; index++) { - this.usesStaticLibrariesCertDigests[index] = sForInternedStringArray.unparcel(in); + this.usesSdkLibraries = sForInternedStringList.unparcel(in); + this.usesSdkLibrariesVersionsMajor = in.createLongArray(); + { + int digestsSize = in.readInt(); + if (digestsSize >= 0) { + this.usesSdkLibrariesCertDigests = new String[digestsSize][]; + for (int index = 0; index < digestsSize; index++) { + this.usesSdkLibrariesCertDigests[index] = sForInternedStringArray.unparcel(in); + } } } @@ -1479,6 +1524,17 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, @Nullable @Override + public String getSdkLibName() { + return sdkLibName; + } + + @Override + public int getSdkLibVersionMajor() { + return sdkLibVersionMajor; + } + + @Nullable + @Override public String getStaticSharedLibName() { return staticSharedLibName; } @@ -1536,6 +1592,18 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return usesStaticLibrariesCertDigests; } + @NonNull + @Override + public List<String> getUsesSdkLibraries() { return usesSdkLibraries; } + + @Nullable + @Override + public long[] getUsesSdkLibrariesVersionsMajor() { return usesSdkLibrariesVersionsMajor; } + + @Nullable + @Override + public String[][] getUsesSdkLibrariesCertDigests() { return usesSdkLibrariesCertDigests; } + @Nullable @Override public String getSharedUserId() { @@ -2083,6 +2151,11 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, } @Override + public boolean isSdkLibrary() { + return getBoolean(Booleans.SDK_LIBRARY); + } + + @Override public boolean isOverlay() { return getBoolean(Booleans.OVERLAY); } @@ -2558,6 +2631,23 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, } @Override + public ParsingPackageImpl setSdkLibName(String sdkLibName) { + this.sdkLibName = TextUtils.safeIntern(sdkLibName); + return this; + } + + @Override + public ParsingPackageImpl setSdkLibVersionMajor(int sdkLibVersionMajor) { + this.sdkLibVersionMajor = sdkLibVersionMajor; + return this; + } + + @Override + public ParsingPackageImpl setSdkLibrary(boolean value) { + return setBoolean(Booleans.SDK_LIBRARY, value); + } + + @Override public ParsingPackageImpl setStaticSharedLibrary(boolean value) { return setBoolean(Booleans.STATIC_SHARED_LIBRARY, value); } diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java index 2933f955bb8c..49b3b08ec5db 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageRead.java +++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java @@ -196,6 +196,17 @@ public interface ParsingPackageRead extends PkgWithoutStateAppInfo, PkgWithoutSt int[] getSplitFlags(); /** + * @see R.styleable#AndroidManifestSdkLibrary_name + */ + @Nullable + String getSdkLibName(); + + /** + * @see R.styleable#AndroidManifestSdkLibrary_versionMajor + */ + int getSdkLibVersionMajor(); + + /** * @see R.styleable#AndroidManifestStaticLibrary_name */ @Nullable @@ -267,6 +278,26 @@ public interface ParsingPackageRead extends PkgWithoutStateAppInfo, PkgWithoutSt @Nullable long[] getUsesStaticLibrariesVersions(); + /** + * TODO(b/135203078): Move SDK library stuff to an inner data class + * + * @see R.styleable#AndroidManifestUsesSdkLibrary + */ + @NonNull + List<String> getUsesSdkLibraries(); + + /** + * @see R.styleable#AndroidManifestUsesSdkLibrary_certDigest + */ + @Nullable + String[][] getUsesSdkLibrariesCertDigests(); + + /** + * @see R.styleable#AndroidManifestUsesSdkLibrary_versionMajor + */ + @Nullable + long[] getUsesSdkLibrariesVersionsMajor(); + boolean hasPreserveLegacyExternalStorage(); /** diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index d2ac87395f62..3e537c874137 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -117,6 +117,7 @@ import com.android.internal.util.XmlUtils; import libcore.io.IoUtils; import libcore.util.EmptyArray; +import libcore.util.HexEncoding; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -848,6 +849,8 @@ public class ParsingPackageUtils { pkg.addProperty(propertyResult.getResult()); } return propertyResult; + case "uses-sdk-library": + return parseUsesSdkLibrary(input, pkg, res, parser); case "uses-static-library": return parseUsesStaticLibrary(input, pkg, res, parser); case "uses-library": @@ -2212,7 +2215,8 @@ public class ParsingPackageUtils { } } - if (TextUtils.isEmpty(pkg.getStaticSharedLibName())) { + if (TextUtils.isEmpty(pkg.getStaticSharedLibName()) && TextUtils.isEmpty( + pkg.getSdkLibName())) { // Add a hidden app detail activity to normal apps which forwards user to App Details // page. ParseResult<ParsedActivity> a = generateAppDetailsHiddenActivity(input, pkg); @@ -2351,10 +2355,14 @@ public class ParsingPackageUtils { pkg.addProperty(propertyResult.getResult()); } return propertyResult; + case "sdk-library": + return parseSdkLibrary(pkg, res, parser, input); case "static-library": return parseStaticLibrary(pkg, res, parser, input); case "library": return parseLibrary(pkg, res, parser, input); + case "uses-sdk-library": + return parseUsesSdkLibrary(input, pkg, res, parser); case "uses-static-library": return parseUsesStaticLibrary(input, pkg, res, parser); case "uses-library": @@ -2375,6 +2383,41 @@ public class ParsingPackageUtils { } @NonNull + private static ParseResult<ParsingPackage> parseSdkLibrary( + ParsingPackage pkg, Resources res, + XmlResourceParser parser, ParseInput input) { + TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestSdkLibrary); + try { + // Note: don't allow this value to be a reference to a resource that may change. + String lname = sa.getNonResourceString( + R.styleable.AndroidManifestSdkLibrary_name); + final int versionMajor = sa.getInt( + R.styleable.AndroidManifestSdkLibrary_versionMajor, + -1); + + // Fail if malformed. + if (lname == null || versionMajor < 0) { + return input.error("Bad sdk-library declaration name: " + lname + + " version: " + versionMajor); + } else if (pkg.getSharedUserId() != null) { + return input.error( + PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID, + "sharedUserId not allowed in SDK library" + ); + } else if (pkg.getSdkLibName() != null) { + return input.error("Multiple SDKs for package " + + pkg.getPackageName()); + } + + return input.success(pkg.setSdkLibName(lname.intern()) + .setSdkLibVersionMajor(versionMajor) + .setSdkLibrary(true)); + } finally { + sa.recycle(); + } + } + + @NonNull private static ParseResult<ParsingPackage> parseStaticLibrary( ParsingPackage pkg, Resources res, XmlResourceParser parser, ParseInput input) { @@ -2436,6 +2479,68 @@ public class ParsingPackageUtils { } @NonNull + private static ParseResult<ParsingPackage> parseUsesSdkLibrary(ParseInput input, + ParsingPackage pkg, Resources res, XmlResourceParser parser) + throws XmlPullParserException, IOException { + TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesSdkLibrary); + try { + // Note: don't allow this value to be a reference to a resource that may change. + String lname = sa.getNonResourceString( + R.styleable.AndroidManifestUsesSdkLibrary_name); + final int versionMajor = sa.getInt( + R.styleable.AndroidManifestUsesSdkLibrary_versionMajor, -1); + String certSha256Digest = sa.getNonResourceString(R.styleable + .AndroidManifestUsesSdkLibrary_certDigest); + + // Since an APK providing a static shared lib can only provide the lib - fail if + // malformed + if (lname == null || versionMajor < 0 || certSha256Digest == null) { + return input.error("Bad uses-sdk-library declaration name: " + lname + + " version: " + versionMajor + " certDigest" + certSha256Digest); + } + + // Can depend only on one version of the same library + List<String> usesSdkLibraries = pkg.getUsesSdkLibraries(); + if (usesSdkLibraries.contains(lname)) { + return input.error( + "Depending on multiple versions of SDK library " + lname); + } + + lname = lname.intern(); + // We allow ":" delimiters in the SHA declaration as this is the format + // emitted by the certtool making it easy for developers to copy/paste. + certSha256Digest = certSha256Digest.replace(":", "").toLowerCase(); + + if ("".equals(certSha256Digest)) { + // Test-only uses-sdk-library empty certificate digest override. + certSha256Digest = SystemProperties.get( + "debug.pm.uses_sdk_library_default_cert_digest", ""); + // Validate the overridden digest. + try { + HexEncoding.decode(certSha256Digest, false); + } catch (IllegalArgumentException e) { + certSha256Digest = ""; + } + } + + ParseResult<String[]> certResult = parseAdditionalCertificates(input, res, parser); + if (certResult.isError()) { + return input.error(certResult); + } + String[] additionalCertSha256Digests = certResult.getResult(); + + final String[] certSha256Digests = new String[additionalCertSha256Digests.length + 1]; + certSha256Digests[0] = certSha256Digest; + System.arraycopy(additionalCertSha256Digests, 0, certSha256Digests, + 1, additionalCertSha256Digests.length); + + return input.success(pkg.addUsesSdkLibrary(lname, versionMajor, certSha256Digests)); + } finally { + sa.recycle(); + } + } + + @NonNull private static ParseResult<ParsingPackage> parseUsesStaticLibrary(ParseInput input, ParsingPackage pkg, Resources res, XmlResourceParser parser) throws XmlPullParserException, IOException { @@ -2483,9 +2588,7 @@ public class ParsingPackageUtils { System.arraycopy(additionalCertSha256Digests, 0, certSha256Digests, 1, additionalCertSha256Digests.length); - return input.success(pkg.addUsesStaticLibrary(lname) - .addUsesStaticLibraryVersion(version) - .addUsesStaticLibraryCertDigests(certSha256Digests)); + return input.success(pkg.addUsesStaticLibrary(lname, version, certSha256Digests)); } finally { sa.recycle(); } diff --git a/core/java/android/content/pm/parsing/PkgWithoutStateAppInfo.java b/core/java/android/content/pm/parsing/PkgWithoutStateAppInfo.java index fcad10c767c3..625b9d1bb479 100644 --- a/core/java/android/content/pm/parsing/PkgWithoutStateAppInfo.java +++ b/core/java/android/content/pm/parsing/PkgWithoutStateAppInfo.java @@ -21,8 +21,6 @@ import android.annotation.Nullable; import android.content.pm.ApplicationInfo; import android.util.SparseArray; -import com.android.internal.R; - /** * Container for fields that are eventually exposed through {@link ApplicationInfo}. * <p> @@ -576,6 +574,11 @@ public interface PkgWithoutStateAppInfo { boolean isStaticSharedLibrary(); /** + * True means that this package/app contains an SDK library. + */ + boolean isSdkLibrary(); + + /** * If omitted from manifest, returns true if {@link #getTargetSdkVersion()} >= {@link * android.os.Build.VERSION_CODES#GINGERBREAD}. * diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 94717b11deb2..fe5811463a72 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -2303,6 +2303,36 @@ <attr name="authorities" /> </declare-styleable> + <!-- The <code>sdk-library</code> tag declares that this apk is providing itself + as an SDK library for other applications to use. Any app can declare an SDK library and there + can be only one SDK library per package. These SDK libraries are updatable, multiple major + versions can be installed at the same time, and an app depends on a specific version. + Other apks can link to it with the {@link #AndroidManifestUsesSdkLibrary uses-sdk-library} tag. + + <p>This appears as a child tag of the {@link #AndroidManifestApplication application} tag. --> + <declare-styleable name="AndroidManifestSdkLibrary" parent="AndroidManifestApplication"> + <!-- Required public name of the SDK library, which other components and packages will use + when referring to this SDK library. This is a string using Java-style scoping to ensure + it is unique. + Both name and version should typically form the apk's package name: name_versionMajor. --> + <attr name="name" /> + <!-- Required major version of the SDK library. --> + <attr name="versionMajor" format="integer" /> + </declare-styleable> + + + <!-- The <code>uses-sdk-library</code> specifies a shared <strong>SDK</strong> library that this + package requires to be present on the device. + + <p>This appears as a child tag of the {@link #AndroidManifestApplication application} tag. --> + <declare-styleable name="AndroidManifestUsesSdkLibrary" parent="AndroidManifestApplication"> + <!-- Required name of the SDK library you use. --> + <attr name="name" /> + <!-- Specify which major version of the SDK library you use. --> + <attr name="versionMajor" format="integer" /> + <!-- The SHA-256 digest of the SDK library signing certificate. --> + <attr name="certDigest" format="string" /> + </declare-styleable> <!-- The <code>static-library</code> tag declares that this apk is providing itself as a static shared library for other applications to use. Any app can declare such diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java index 2d61773e6796..9b2179026124 100644 --- a/services/core/java/com/android/server/pm/ComputerEngine.java +++ b/services/core/java/com/android/server/pm/ComputerEngine.java @@ -2232,11 +2232,12 @@ public class ComputerEngine implements Computer { return false; } - public final boolean filterSharedLibPackage(@Nullable PackageStateInternal ps, int uid, + private boolean filterStaticSharedLibPackage(@Nullable PackageStateInternal ps, int uid, int userId, @PackageManager.ComponentInfoFlags long flags) { - // Callers can access only the libs they depend on, otherwise they need to explicitly - // ask for the shared libraries given the caller is allowed to access all static libs. - if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) { + // Callers can access only the static shared libs they depend on, otherwise they need to + // explicitly ask for the static shared libraries given the caller is allowed to access + // all static libs. + if ((flags & PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES) != 0) { // System/shell/root get to see all static libs final int appId = UserHandle.getAppId(uid); if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID @@ -2287,6 +2288,69 @@ public class ComputerEngine implements Computer { return true; } + private boolean filterSdkLibPackage(@Nullable PackageStateInternal ps, int uid, + int userId, @PackageManager.ComponentInfoFlags long flags) { + // Callers can access only the SDK libs they depend on, otherwise they need to + // explicitly ask for the SDKs given the caller is allowed to access + // all shared libs. + if ((flags & PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES) != 0) { + // System/shell/root get to see all SDK libs. + final int appId = UserHandle.getAppId(uid); + if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID + || appId == Process.ROOT_UID) { + return false; + } + // Installer gets to see all SDK libs. + if (PackageManager.PERMISSION_GRANTED + == checkUidPermission(Manifest.permission.INSTALL_PACKAGES, uid)) { + return false; + } + } + + // No package means no static lib as it is always on internal storage + if (ps == null || ps.getPkg() == null || !ps.getPkg().isSdkLibrary()) { + return false; + } + + final SharedLibraryInfo libraryInfo = getSharedLibraryInfo( + ps.getPkg().getSdkLibName(), ps.getPkg().getSdkLibVersionMajor()); + if (libraryInfo == null) { + return false; + } + + final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid)); + final String[] uidPackageNames = getPackagesForUid(resolvedUid); + if (uidPackageNames == null) { + return true; + } + + for (String uidPackageName : uidPackageNames) { + if (ps.getPackageName().equals(uidPackageName)) { + return false; + } + PackageStateInternal uidPs = mSettings.getPackage(uidPackageName); + if (uidPs != null) { + final int index = ArrayUtils.indexOf(uidPs.getUsesSdkLibraries(), + libraryInfo.getName()); + if (index < 0) { + continue; + } + if (uidPs.getPkg().getUsesSdkLibrariesVersionsMajor()[index] + == libraryInfo.getLongVersion()) { + return false; + } + } + } + return true; + } + + @Override + public final boolean filterSharedLibPackage(@Nullable PackageStateInternal ps, int uid, + int userId, @PackageManager.ComponentInfoFlags long flags) { + return filterStaticSharedLibPackage(ps, uid, userId, flags) || filterSdkLibPackage(ps, uid, + userId, flags); + } + private boolean hasCrossUserPermission( int callingUid, int callingUserId, int userId, boolean requireFullPermission, boolean requirePermissionWhenSameUser) { @@ -3719,7 +3783,7 @@ public class ComputerEngine implements Computer { flags = updateFlagsForPackage(flags, userId); - final boolean canSeeStaticLibraries = + final boolean canSeeStaticAndSdkLibraries = mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES) == PERMISSION_GRANTED || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES) @@ -3744,7 +3808,7 @@ public class ComputerEngine implements Computer { final int versionCount = versionedLib.size(); for (int j = 0; j < versionCount; j++) { SharedLibraryInfo libInfo = versionedLib.valueAt(j); - if (!canSeeStaticLibraries && libInfo.isStatic()) { + if (!canSeeStaticAndSdkLibraries && (libInfo.isStatic() || libInfo.isSdk())) { break; } final long identity = Binder.clearCallingIdentity(); @@ -3753,7 +3817,7 @@ public class ComputerEngine implements Computer { PackageInfo packageInfo = getPackageInfoInternal( declaringPackage.getPackageName(), declaringPackage.getLongVersionCode(), - flags | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, + flags | PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES, Binder.getCallingUid(), userId); if (packageInfo == null) { continue; @@ -3853,12 +3917,17 @@ public class ComputerEngine implements Computer { } final String libName = libInfo.getName(); - if (libInfo.isStatic()) { - final int libIdx = ArrayUtils.indexOf(ps.getUsesStaticLibraries(), libName); + if (libInfo.isStatic() || libInfo.isSdk()) { + final String[] libs = + libInfo.isStatic() ? ps.getUsesStaticLibraries() : ps.getUsesSdkLibraries(); + final long[] libsVersions = libInfo.isStatic() ? ps.getUsesStaticLibrariesVersions() + : ps.getUsesSdkLibrariesVersionsMajor(); + + final int libIdx = ArrayUtils.indexOf(libs, libName); if (libIdx < 0) { continue; } - if (ps.getUsesStaticLibrariesVersions()[libIdx] != libInfo.getLongVersion()) { + if (libsVersions[libIdx] != libInfo.getLongVersion()) { continue; } if (shouldFilterApplication(ps, callingUid, userId)) { @@ -3939,7 +4008,7 @@ public class ComputerEngine implements Computer { PackageInfo packageInfo = getPackageInfoInternal( declaringPackage.getPackageName(), declaringPackage.getLongVersionCode(), - flags | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, + flags | PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES, Binder.getCallingUid(), userId); if (packageInfo == null) { continue; @@ -4034,7 +4103,7 @@ public class ComputerEngine implements Computer { getPackageStateInternal(libraryInfo.getPackageName()); if (ps != null && !filterSharedLibPackage(ps, Binder.getCallingUid(), UserHandle.getUserId(Binder.getCallingUid()), - PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) { + PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES)) { if (libs == null) { libs = new ArraySet<>(); } diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java index 43d60ccd1aec..641f24f711c1 100644 --- a/services/core/java/com/android/server/pm/DeletePackageHelper.java +++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java @@ -164,9 +164,16 @@ final class DeletePackageHelper { allUsers = mUserManagerInternal.getUserIds(); - if (pkg != null && pkg.getStaticSharedLibName() != null) { - SharedLibraryInfo libraryInfo = mPm.getSharedLibraryInfo( - pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion()); + if (pkg != null) { + SharedLibraryInfo libraryInfo = null; + if (pkg.getStaticSharedLibName() != null) { + libraryInfo = mPm.getSharedLibraryInfo(pkg.getStaticSharedLibName(), + pkg.getStaticSharedLibVersion()); + } else if (pkg.getSdkLibName() != null) { + libraryInfo = mPm.getSharedLibraryInfo(pkg.getSdkLibName(), + pkg.getSdkLibVersionMajor()); + } + if (libraryInfo != null) { for (int currUserId : allUsers) { if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) { @@ -828,9 +835,10 @@ final class DeletePackageHelper { continue; } final String packageName = ps.getPkg().getPackageName(); - // Skip over if system app or static shared library + // Skip over if system app, static shared library or and SDK library. if ((ps.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0 - || !TextUtils.isEmpty(ps.getPkg().getStaticSharedLibName())) { + || !TextUtils.isEmpty(ps.getPkg().getStaticSharedLibName()) + || !TextUtils.isEmpty(ps.getPkg().getSdkLibName())) { continue; } if (DEBUG_CLEAN_APKS) { diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index 5ca0618d723f..d2087ee6125a 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -254,12 +254,11 @@ final class InstallPackageHelper { final List<SharedLibraryInfo> allowedSharedLibInfos = SharedLibraryHelper.getAllowedSharedLibInfos(scanResult, request.mSharedLibrarySource); - final SharedLibraryInfo staticLib = scanResult.mStaticSharedLibraryInfo; if (allowedSharedLibInfos != null) { for (SharedLibraryInfo info : allowedSharedLibInfos) { if (!SharedLibraryHelper.addSharedLibraryToPackageVersionMap( incomingSharedLibraries, info)) { - throw new ReconcileFailure("Static Shared Library " + staticLib.getName() + throw new ReconcileFailure("Shared Library " + info.getName() + " is being installed twice in this set!"); } } @@ -1188,7 +1187,8 @@ final class InstallPackageHelper { createdAppId.put(packageName, optimisticallyRegisterAppId(result)); versionInfos.put(result.mPkgSetting.getPkg().getPackageName(), mPm.getSettingsVersionForPackage(result.mPkgSetting.getPkg())); - if (result.mStaticSharedLibraryInfo != null) { + if (result.mStaticSharedLibraryInfo != null + || result.mSdkSharedLibraryInfo != null) { final PackageSetting sharedLibLatestVersionSetting = mPm.getSharedLibLatestVersionSetting(result); if (sharedLibLatestVersionSetting != null) { @@ -2695,7 +2695,7 @@ final class InstallPackageHelper { } } - if (dataOwnerPkg != null) { + if (dataOwnerPkg != null && !dataOwnerPkg.isSdkLibrary()) { if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags, dataOwnerPkg.isDebuggable())) { try { diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 4767d3a4c065..26a5bbb094ac 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -1328,7 +1328,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements PackageInfo packageInfo = null; try { packageInfo = AppGlobals.getPackageManager().getPackageInfo( - basePackageName, PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId); + basePackageName, PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES, userId); } catch (RemoteException ignored) { } if (packageInfo == null || packageInfo.applicationInfo == null) { diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index f299e1e6bec0..28204eadd394 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -2903,7 +2903,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final PackageInfo pkgInfo = mPm.getPackageInfo( params.appPackageName, PackageManager.GET_SIGNATURES - | PackageManager.MATCH_STATIC_SHARED_LIBRARIES /*flags*/, userId); + | PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES /*flags*/, userId); // Partial installs must be consistent with existing install if (params.mode == SessionParams.MODE_INHERIT_EXISTING diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 9f5adcb6f16f..fe5bce1306f8 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4034,7 +4034,13 @@ public class PackageManagerService extends IPackageManager.Stub // - Package manager is in a state where package isn't scanned yet. This will // get called again after scanning to fix the dependencies. if (AndroidPackageUtils.isLibrary(pkg)) { - if (pkg.getStaticSharedLibName() != null) { + if (pkg.getSdkLibName() != null) { + SharedLibraryInfo definedLibrary = getSharedLibraryInfo( + pkg.getSdkLibName(), pkg.getSdkLibVersionMajor()); + if (definedLibrary != null) { + action.accept(definedLibrary, libInfo); + } + } else if (pkg.getStaticSharedLibName() != null) { SharedLibraryInfo definedLibrary = getSharedLibraryInfo( pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion()); if (definedLibrary != null) { @@ -4186,7 +4192,9 @@ public class PackageManagerService extends IPackageManager.Stub && !hasString(pkg.getUsesLibraries(), changingPkg.getLibraryNames()) && !hasString(pkg.getUsesOptionalLibraries(), changingPkg.getLibraryNames()) && !ArrayUtils.contains(pkg.getUsesStaticLibraries(), - changingPkg.getStaticSharedLibName())) { + changingPkg.getStaticSharedLibName()) + && !ArrayUtils.contains(pkg.getUsesSdkLibraries(), + changingPkg.getSdkLibName())) { continue; } if (resultList == null) { @@ -4477,15 +4485,24 @@ public class PackageManagerService extends IPackageManager.Stub Slog.w(TAG, "Cannot hide package: android"); return false; } - // Cannot hide static shared libs as they are considered - // a part of the using app (emulating static linking). Also - // static libs are installed always on internal storage. AndroidPackage pkg = mPackages.get(packageName); - if (pkg != null && pkg.getStaticSharedLibName() != null) { - Slog.w(TAG, "Cannot hide package: " + packageName - + " providing static shared library: " - + pkg.getStaticSharedLibName()); - return false; + if (pkg != null) { + // Cannot hide SDK libs as they are controlled by SDK manager. + if (pkg.getSdkLibName() != null) { + Slog.w(TAG, "Cannot hide package: " + packageName + + " providing SDK library: " + + pkg.getSdkLibName()); + return false; + } + // Cannot hide static shared libs as they are considered + // a part of the using app (emulating static linking). Also + // static libs are installed always on internal storage. + if (pkg.getStaticSharedLibName() != null) { + Slog.w(TAG, "Cannot hide package: " + packageName + + " providing static shared library: " + + pkg.getStaticSharedLibName()); + return false; + } } // Only allow protected packages to hide themselves. if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.getAppId()) @@ -5154,15 +5171,24 @@ public class PackageManagerService extends IPackageManager.Stub continue; } - // Cannot suspend static shared libs as they are considered - // a part of the using app (emulating static linking). Also - // static libs are installed always on internal storage. AndroidPackage pkg = mPackages.get(packageName); - if (pkg != null && pkg.isStaticSharedLibrary()) { - Slog.w(TAG, "Cannot suspend package: " + packageName - + " providing static shared library: " - + pkg.getStaticSharedLibName()); - continue; + if (pkg != null) { + // Cannot suspend SDK libs as they are controlled by SDK manager. + if (pkg.isSdkLibrary()) { + Slog.w(TAG, "Cannot suspend package: " + packageName + + " providing SDK library: " + + pkg.getSdkLibName()); + continue; + } + // Cannot suspend static shared libs as they are considered + // a part of the using app (emulating static linking). Also + // static libs are installed always on internal storage. + if (pkg.isStaticSharedLibrary()) { + Slog.w(TAG, "Cannot suspend package: " + packageName + + " providing static shared library: " + + pkg.getStaticSharedLibName()); + continue; + } } } if (PLATFORM_PACKAGE_NAME.equals(packageName)) { @@ -5612,14 +5638,22 @@ public class PackageManagerService extends IPackageManager.Stub android.Manifest.permission.DELETE_PACKAGES, null); // TODO (b/157774108): This should fail on non-existent packages. synchronized (mLock) { - // Cannot block uninstall of static shared libs as they are - // considered a part of the using app (emulating static linking). - // Also static libs are installed always on internal storage. AndroidPackage pkg = mPackages.get(packageName); - if (pkg != null && pkg.getStaticSharedLibName() != null) { - Slog.w(TAG, "Cannot block uninstall of package: " + packageName - + " providing static shared library: " + pkg.getStaticSharedLibName()); - return false; + if (pkg != null) { + // Cannot block uninstall SDK libs as they are controlled by SDK manager. + if (pkg.getSdkLibName() != null) { + Slog.w(TAG, "Cannot block uninstall of package: " + packageName + + " providing SDK library: " + pkg.getSdkLibName()); + return false; + } + // Cannot block uninstall of static shared libs as they are + // considered a part of the using app (emulating static linking). + // Also static libs are installed always on internal storage. + if (pkg.getStaticSharedLibName() != null) { + Slog.w(TAG, "Cannot block uninstall of package: " + packageName + + " providing static shared library: " + pkg.getStaticSharedLibName()); + return false; + } } mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall); mSettings.writePackageRestrictionsLPr(userId); diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index fb704700ca6f..0564e858c84c 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -49,6 +49,7 @@ import android.content.pm.ParceledListSlice; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; +import android.content.pm.SharedLibraryInfo; import android.content.pm.SuspendDialogInfo; import android.content.pm.UserInfo; import android.content.pm.VersionedPackage; @@ -667,6 +668,8 @@ class PackageManagerShellCommand extends ShellCommand { return runListPermissions(); case "staged-sessions": return runListStagedSessions(); + case "sdks": + return runListSdks(); case "users": ServiceManager.getService("user").shellCommand( getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(), @@ -792,6 +795,15 @@ class PackageManagerShellCommand extends ShellCommand { } private int runListPackages(boolean showSourceDir) throws RemoteException { + return runListPackages(showSourceDir, false); + } + + private int runListSdks() throws RemoteException { + return runListPackages(false, true); + } + + private int runListPackages(boolean showSourceDir, boolean showSdks) throws RemoteException { + final String prefix = showSdks ? "sdk:" : "package:"; final PrintWriter pw = getOutPrintWriter(); int getFlags = 0; boolean listDisabled = false, listEnabled = false; @@ -866,6 +878,9 @@ class PackageManagerShellCommand extends ShellCommand { if (userId == UserHandle.USER_ALL) { getFlags |= PackageManager.MATCH_KNOWN_PACKAGES; } + if (showSdks) { + getFlags |= PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES; + } final int translatedUserId = translateUserId(userId, UserHandle.USER_SYSTEM, "runListPackages"); @SuppressWarnings("unchecked") @@ -885,37 +900,61 @@ class PackageManagerShellCommand extends ShellCommand { } final boolean isSystem = !isApex && - (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0; + (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; final boolean isEnabled = !isApex && info.applicationInfo.enabled; - if ((!listDisabled || !isEnabled) && - (!listEnabled || isEnabled) && - (!listSystem || isSystem) && - (!listThirdParty || !isSystem) && - (!listApexOnly || isApex)) { - pw.print("package:"); - if (showSourceDir) { - pw.print(info.applicationInfo.sourceDir); - pw.print("="); + if ((listDisabled && isEnabled) || + (listEnabled && !isEnabled) || + (listSystem && !isSystem) || + (listThirdParty && isSystem) || + (listApexOnly && !isApex)) { + continue; + } + + String name = null; + if (showSdks) { + final ParceledListSlice<SharedLibraryInfo> libsSlice = + mInterface.getDeclaredSharedLibraries(info.packageName, getFlags, userId); + if (libsSlice == null) { + continue; } - pw.print(info.packageName); - if (showVersionCode) { - pw.print(" versionCode:"); - if (info.applicationInfo != null) { - pw.print(info.applicationInfo.longVersionCode); - } else { - pw.print(info.getLongVersionCode()); + final List<SharedLibraryInfo> libs = libsSlice.getList(); + for (int l = 0, lsize = libs.size(); l < lsize; ++l) { + SharedLibraryInfo lib = libs.get(l); + if (lib.getType() == SharedLibraryInfo.TYPE_SDK) { + name = lib.getName() + ":" + lib.getLongVersion(); + break; } } - if (listInstaller) { - pw.print(" installer="); - pw.print(mInterface.getInstallerPackageName(info.packageName)); + if (name == null) { + continue; } - if (showUid && !isApex) { - pw.print(" uid:"); - pw.print(info.applicationInfo.uid); + } else { + name = info.packageName; + } + + pw.print(prefix); + if (showSourceDir) { + pw.print(info.applicationInfo.sourceDir); + pw.print("="); + } + pw.print(name); + if (showVersionCode) { + pw.print(" versionCode:"); + if (info.applicationInfo != null) { + pw.print(info.applicationInfo.longVersionCode); + } else { + pw.print(info.getLongVersionCode()); } - pw.println(); } + if (listInstaller) { + pw.print(" installer="); + pw.print(mInterface.getInstallerPackageName(info.packageName)); + } + if (showUid && !isApex) { + pw.print(" uid:"); + pw.print(info.applicationInfo.uid); + } + pw.println(); } return 0; } @@ -2060,7 +2099,7 @@ class PackageManagerShellCommand extends ShellCommand { } else { if ((flags & PackageManager.DELETE_ALL_USERS) == 0) { final PackageInfo info = mInterface.getPackageInfo(packageName, - PackageManager.MATCH_STATIC_SHARED_LIBRARIES, translatedUserId); + PackageManager.MATCH_STATIC_SHARED_AND_SDK_LIBRARIES, translatedUserId); if (info == null) { pw.println("Failure [not installed for " + translatedUserId + "]"); return 1; diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java index dc514c10a5fc..923a133338ab 100644 --- a/services/core/java/com/android/server/pm/PackageSetting.java +++ b/services/core/java/com/android/server/pm/PackageSetting.java @@ -32,12 +32,6 @@ import android.content.pm.SigningInfo; import android.content.pm.SuspendDialogInfo; import android.content.pm.UserInfo; import android.content.pm.overlay.OverlayPaths; - -import com.android.server.pm.pkg.PackageStateInternal; -import com.android.server.pm.pkg.PackageUserState; -import com.android.server.pm.pkg.PackageUserStateImpl; -import com.android.server.pm.pkg.PackageUserStateInternal; -import com.android.server.pm.pkg.SuspendParams; import android.os.PersistableBundle; import android.service.pm.PackageProto; import android.util.ArrayMap; @@ -53,7 +47,12 @@ import com.android.server.pm.permission.LegacyPermissionDataProvider; import com.android.server.pm.permission.LegacyPermissionState; import com.android.server.pm.pkg.AndroidPackageApi; import com.android.server.pm.pkg.PackageState; +import com.android.server.pm.pkg.PackageStateInternal; import com.android.server.pm.pkg.PackageStateUnserialized; +import com.android.server.pm.pkg.PackageUserState; +import com.android.server.pm.pkg.PackageUserStateImpl; +import com.android.server.pm.pkg.PackageUserStateInternal; +import com.android.server.pm.pkg.SuspendParams; import com.android.server.utils.SnapshotCache; import libcore.util.EmptyArray; @@ -94,6 +93,12 @@ public class PackageSetting extends SettingBase implements PackageStateInternal private Set<String> mOldCodePaths; @Nullable + private String[] usesSdkLibraries; + + @Nullable + private long[] usesSdkLibrariesVersionsMajor; + + @Nullable private String[] usesStaticLibraries; @Nullable @@ -208,12 +213,16 @@ public class PackageSetting extends SettingBase implements PackageStateInternal String legacyNativeLibraryPath, String primaryCpuAbi, String secondaryCpuAbi, String cpuAbiOverride, long longVersionCode, int pkgFlags, int pkgPrivateFlags, - int sharedUserId, String[] usesStaticLibraries, - long[] usesStaticLibrariesVersions, Map<String, Set<String>> mimeGroups, + int sharedUserId, + String[] usesSdkLibraries, long[] usesSdkLibrariesVersionsMajor, + String[] usesStaticLibraries, long[] usesStaticLibrariesVersions, + Map<String, Set<String>> mimeGroups, @NonNull UUID domainSetId) { super(pkgFlags, pkgPrivateFlags); this.mName = name; this.mRealName = realName; + this.usesSdkLibraries = usesSdkLibraries; + this.usesSdkLibrariesVersionsMajor = usesSdkLibrariesVersionsMajor; this.usesStaticLibraries = usesStaticLibraries; this.usesStaticLibrariesVersions = usesStaticLibrariesVersions; this.mPath = path; @@ -617,6 +626,13 @@ public class PackageSetting extends SettingBase implements PackageStateInternal forceQueryableOverride = other.forceQueryableOverride; mDomainSetId = other.mDomainSetId; + usesSdkLibraries = other.usesSdkLibraries != null + ? Arrays.copyOf(other.usesSdkLibraries, + other.usesSdkLibraries.length) : null; + usesSdkLibrariesVersionsMajor = other.usesSdkLibrariesVersionsMajor != null + ? Arrays.copyOf(other.usesSdkLibrariesVersionsMajor, + other.usesSdkLibrariesVersionsMajor.length) : null; + usesStaticLibraries = other.usesStaticLibraries != null ? Arrays.copyOf(other.usesStaticLibraries, other.usesStaticLibraries.length) : null; @@ -1225,6 +1241,19 @@ public class PackageSetting extends SettingBase implements PackageStateInternal @NonNull @Override + public String[] getUsesSdkLibraries() { + return usesSdkLibraries == null ? EmptyArray.STRING : usesSdkLibraries; + } + + @NonNull + @Override + public long[] getUsesSdkLibrariesVersionsMajor() { + return usesSdkLibrariesVersionsMajor == null ? EmptyArray.LONG + : usesSdkLibrariesVersionsMajor; + } + + @NonNull + @Override public String[] getUsesStaticLibraries() { return usesStaticLibraries == null ? EmptyArray.STRING : usesStaticLibraries; } @@ -1300,6 +1329,18 @@ public class PackageSetting extends SettingBase implements PackageStateInternal return this; } + public PackageSetting setUsesSdkLibraries(String[] usesSdkLibraries) { + this.usesSdkLibraries = usesSdkLibraries; + onChanged(); + return this; + } + + public PackageSetting setUsesSdkLibrariesVersionsMajor(long[] usesSdkLibrariesVersions) { + this.usesSdkLibrariesVersionsMajor = usesSdkLibrariesVersions; + onChanged(); + return this; + } + public PackageSetting setUsesStaticLibraries(String[] usesStaticLibraries) { this.usesStaticLibraries = usesStaticLibraries; onChanged(); diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java index 48b893bda546..749495c5a5b4 100644 --- a/services/core/java/com/android/server/pm/RemovePackageHelper.java +++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java @@ -189,7 +189,19 @@ final class RemovePackageHelper { r = null; - // Any package can hold static shared libraries. + // Any package can hold SDK or static shared libraries. + if (pkg.getSdkLibName() != null) { + if (removeSharedLibraryLPw(pkg.getSdkLibName(), pkg.getSdkLibVersionMajor())) { + if (DEBUG_REMOVE && chatty) { + if (r == null) { + r = new StringBuilder(256); + } else { + r.append(' '); + } + r.append(pkg.getSdkLibName()); + } + } + } if (pkg.getStaticSharedLibName() != null) { if (removeSharedLibraryLPw(pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion())) { diff --git a/services/core/java/com/android/server/pm/ScanPackageHelper.java b/services/core/java/com/android/server/pm/ScanPackageHelper.java index 9b08ef9b3525..eafe0d98e505 100644 --- a/services/core/java/com/android/server/pm/ScanPackageHelper.java +++ b/services/core/java/com/android/server/pm/ScanPackageHelper.java @@ -294,6 +294,12 @@ final class ScanPackageHelper { } } + String[] usesSdkLibraries = null; + if (!parsedPackage.getUsesSdkLibraries().isEmpty()) { + usesSdkLibraries = new String[parsedPackage.getUsesSdkLibraries().size()]; + parsedPackage.getUsesSdkLibraries().toArray(usesSdkLibraries); + } + String[] usesStaticLibraries = null; if (!parsedPackage.getUsesStaticLibraries().isEmpty()) { usesStaticLibraries = new String[parsedPackage.getUsesStaticLibraries().size()]; @@ -324,7 +330,8 @@ final class ScanPackageHelper { AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage), parsedPackage.getLongVersionCode(), pkgFlags, pkgPrivateFlags, user, true /*allowInstall*/, instantApp, virtualPreload, - UserManagerService.getInstance(), usesStaticLibraries, + UserManagerService.getInstance(), usesSdkLibraries, + parsedPackage.getUsesSdkLibrariesVersionsMajor(), usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups(), newDomainSetId); } else { @@ -344,6 +351,7 @@ final class ScanPackageHelper { PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting), PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting), UserManagerService.getInstance(), + usesSdkLibraries, parsedPackage.getUsesSdkLibrariesVersionsMajor(), usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups(), newDomainSetId); } @@ -552,6 +560,10 @@ final class ScanPackageHelper { pkgSetting.setVolumeUuid(volumeUuid); } + SharedLibraryInfo sdkLibraryInfo = null; + if (!TextUtils.isEmpty(parsedPackage.getSdkLibName())) { + sdkLibraryInfo = AndroidPackageUtils.createSharedLibraryForSdk(parsedPackage); + } SharedLibraryInfo staticSharedLibraryInfo = null; if (!TextUtils.isEmpty(parsedPackage.getStaticSharedLibName())) { staticSharedLibraryInfo = @@ -568,7 +580,7 @@ final class ScanPackageHelper { return new ScanResult(request, true, pkgSetting, changedAbiCodePath, !createNewPackage /* existingSettingCopied */, - previousAppId, staticSharedLibraryInfo, + previousAppId, sdkLibraryInfo, staticSharedLibraryInfo, dynamicSharedLibraryInfos); } diff --git a/services/core/java/com/android/server/pm/ScanResult.java b/services/core/java/com/android/server/pm/ScanResult.java index eb44a82af911..f77be1f9b2d3 100644 --- a/services/core/java/com/android/server/pm/ScanResult.java +++ b/services/core/java/com/android/server/pm/ScanResult.java @@ -51,6 +51,8 @@ final class ScanResult { /** ABI code paths that have changed in the package scan */ @Nullable public final List<String> mChangedAbiCodePath; + public final SharedLibraryInfo mSdkSharedLibraryInfo; + public final SharedLibraryInfo mStaticSharedLibraryInfo; public final List<SharedLibraryInfo> mDynamicSharedLibraryInfos; @@ -60,6 +62,7 @@ final class ScanResult { @Nullable PackageSetting pkgSetting, @Nullable List<String> changedAbiCodePath, boolean existingSettingCopied, int previousAppId, + SharedLibraryInfo sdkSharedLibraryInfo, SharedLibraryInfo staticSharedLibraryInfo, List<SharedLibraryInfo> dynamicSharedLibraryInfos) { mRequest = request; @@ -68,6 +71,7 @@ final class ScanResult { mChangedAbiCodePath = changedAbiCodePath; mExistingSettingCopied = existingSettingCopied; mPreviousAppId = previousAppId; + mSdkSharedLibraryInfo = sdkSharedLibraryInfo; mStaticSharedLibraryInfo = staticSharedLibraryInfo; mDynamicSharedLibraryInfos = dynamicSharedLibraryInfos; } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 6a163b2fdacb..45994f65d697 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -276,6 +276,7 @@ public final class Settings implements Watchable, Snappable { private static final String TAG_RUNTIME_PERMISSIONS = "runtime-permissions"; private static final String TAG_PERMISSIONS = "perms"; private static final String TAG_CHILD_PACKAGE = "child-package"; + private static final String TAG_USES_SDK_LIB = "uses-sdk-lib"; private static final String TAG_USES_STATIC_LIB = "uses-static-lib"; private static final String TAG_BLOCK_UNINSTALL_PACKAGES = "block-uninstall-packages"; private static final String TAG_BLOCK_UNINSTALL = "block-uninstall"; @@ -826,6 +827,7 @@ public final class Settings implements Watchable, Snappable { p.getLegacyNativeLibraryPath(), p.getPrimaryCpuAbi(), p.getSecondaryCpuAbi(), p.getCpuAbiOverride(), p.getAppId(), p.getVersionCode(), p.getFlags(), p.getPrivateFlags(), + p.getUsesSdkLibraries(), p.getUsesSdkLibrariesVersionsMajor(), p.getUsesStaticLibraries(), p.getUsesStaticLibrariesVersions(), p.getMimeGroups(), mDomainVerificationManager.generateNewId()); if (ret != null) { @@ -849,9 +851,10 @@ public final class Settings implements Watchable, Snappable { PackageSetting addPackageLPw(String name, String realName, File codePath, String legacyNativeLibraryPathString, String primaryCpuAbiString, - String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, long vc, int - pkgFlags, int pkgPrivateFlags, String[] usesStaticLibraries, - long[] usesStaticLibraryNames, Map<String, Set<String>> mimeGroups, + String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, long vc, + int pkgFlags, int pkgPrivateFlags, String[] usesSdkLibraries, + long[] usesSdkLibrariesVersions, String[] usesStaticLibraries, + long[] usesStaticLibrariesVersions, Map<String, Set<String>> mimeGroups, @NonNull UUID domainSetId) { PackageSetting p = mPackages.get(name); if (p != null) { @@ -864,8 +867,8 @@ public final class Settings implements Watchable, Snappable { } p = new PackageSetting(name, realName, codePath, legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, vc, pkgFlags, - pkgPrivateFlags, 0 /*userId*/, usesStaticLibraries, usesStaticLibraryNames, - mimeGroups, domainSetId); + pkgPrivateFlags, 0 /*userId*/, usesSdkLibraries, usesSdkLibrariesVersions, + usesStaticLibraries, usesStaticLibrariesVersions, mimeGroups, domainSetId); p.setAppId(uid); if (registerExistingAppIdLPw(uid, p, name)) { mPackages.put(name, p); @@ -925,6 +928,7 @@ public final class Settings implements Watchable, Snappable { String secondaryCpuAbi, long versionCode, int pkgFlags, int pkgPrivateFlags, UserHandle installUser, boolean allowInstall, boolean instantApp, boolean virtualPreload, UserManagerService userManager, + String[] usesSdkLibraries, long[] usesSdkLibrariesVersions, String[] usesStaticLibraries, long[] usesStaticLibrariesVersions, Set<String> mimeGroupNames, @NonNull UUID domainSetId) { final PackageSetting pkgSetting; @@ -940,6 +944,8 @@ public final class Settings implements Watchable, Snappable { // overwrite the signatures in the original package setting. .setSignatures(new PackageSignatures()) .setLongVersionCode(versionCode) + .setUsesSdkLibraries(usesSdkLibraries) + .setUsesSdkLibrariesVersionsMajor(usesSdkLibrariesVersions) .setUsesStaticLibraries(usesStaticLibraries) .setUsesStaticLibrariesVersions(usesStaticLibrariesVersions) // Update new package state. @@ -951,8 +957,9 @@ public final class Settings implements Watchable, Snappable { pkgSetting = new PackageSetting(pkgName, realPkgName, codePath, legacyNativeLibraryPath, primaryCpuAbi, secondaryCpuAbi, null /*cpuAbiOverrideString*/, versionCode, pkgFlags, pkgPrivateFlags, - 0 /*sharedUserId*/, usesStaticLibraries, - usesStaticLibrariesVersions, createMimeGroups(mimeGroupNames), domainSetId); + 0 /*sharedUserId*/, usesSdkLibraries, usesSdkLibrariesVersions, + usesStaticLibraries, usesStaticLibrariesVersions, + createMimeGroups(mimeGroupNames), domainSetId); pkgSetting.setLastModifiedTime(codePath.lastModified()); pkgSetting.setSharedUser(sharedUser); // If this is not a system app, it starts out stopped. @@ -1046,6 +1053,7 @@ public final class Settings implements Watchable, Snappable { @NonNull File codePath, @Nullable String legacyNativeLibraryPath, @Nullable String primaryCpuAbi, @Nullable String secondaryCpuAbi, int pkgFlags, int pkgPrivateFlags, @NonNull UserManagerService userManager, + @Nullable String[] usesSdkLibraries, @Nullable long[] usesSdkLibrariesVersions, @Nullable String[] usesStaticLibraries, @Nullable long[] usesStaticLibrariesVersions, @Nullable Set<String> mimeGroupNames, @NonNull UUID domainSetId) throws PackageManagerException { @@ -1095,7 +1103,17 @@ public final class Settings implements Watchable, Snappable { .setSecondaryCpuAbi(secondaryCpuAbi) .updateMimeGroups(mimeGroupNames) .setDomainSetId(domainSetId); - // Update static shared library dependencies if needed + // Update SDK library dependencies if needed. + if (usesSdkLibraries != null && usesSdkLibrariesVersions != null + && usesSdkLibraries.length == usesSdkLibrariesVersions.length) { + pkgSetting.setUsesSdkLibraries(usesSdkLibraries) + .setUsesSdkLibrariesVersionsMajor(usesSdkLibrariesVersions); + } else { + pkgSetting.setUsesSdkLibraries(null) + .setUsesSdkLibrariesVersionsMajor(null); + } + + // Update static shared library dependencies if needed. if (usesStaticLibraries != null && usesStaticLibrariesVersions != null && usesStaticLibraries.length == usesStaticLibrariesVersions.length) { pkgSetting.setUsesStaticLibraries(usesStaticLibraries) @@ -2167,6 +2185,21 @@ public final class Settings implements Watchable, Snappable { } } + void readUsesSdkLibLPw(TypedXmlPullParser parser, PackageSetting outPs) + throws IOException, XmlPullParserException { + String libName = parser.getAttributeValue(null, ATTR_NAME); + long libVersion = parser.getAttributeLong(null, ATTR_VERSION, -1); + + if (libName != null && libVersion >= 0) { + outPs.setUsesSdkLibraries(ArrayUtils.appendElement(String.class, + outPs.getUsesSdkLibraries(), libName)); + outPs.setUsesSdkLibrariesVersionsMajor(ArrayUtils.appendLong( + outPs.getUsesSdkLibrariesVersionsMajor(), libVersion)); + } + + XmlUtils.skipCurrentTag(parser); + } + void readUsesStaticLibLPw(TypedXmlPullParser parser, PackageSetting outPs) throws IOException, XmlPullParserException { String libName = parser.getAttributeValue(null, ATTR_NAME); @@ -2182,6 +2215,23 @@ public final class Settings implements Watchable, Snappable { XmlUtils.skipCurrentTag(parser); } + void writeUsesSdkLibLPw(TypedXmlSerializer serializer, String[] usesSdkLibraries, + long[] usesSdkLibraryVersions) throws IOException { + if (ArrayUtils.isEmpty(usesSdkLibraries) || ArrayUtils.isEmpty(usesSdkLibraryVersions) + || usesSdkLibraries.length != usesSdkLibraryVersions.length) { + return; + } + final int libCount = usesSdkLibraries.length; + for (int i = 0; i < libCount; i++) { + final String libName = usesSdkLibraries[i]; + final long libVersion = usesSdkLibraryVersions[i]; + serializer.startTag(null, TAG_USES_SDK_LIB); + serializer.attribute(null, ATTR_NAME, libName); + serializer.attributeLong(null, ATTR_VERSION, libVersion); + serializer.endTag(null, TAG_USES_SDK_LIB); + } + } + void writeUsesStaticLibLPw(TypedXmlSerializer serializer, String[] usesStaticLibraries, long[] usesStaticLibraryVersions) throws IOException { if (ArrayUtils.isEmpty(usesStaticLibraries) || ArrayUtils.isEmpty(usesStaticLibraryVersions) @@ -2707,6 +2757,9 @@ public final class Settings implements Watchable, Snappable { } serializer.attributeFloat(null, "loadingProgress", pkg.getLoadingProgress()); + writeUsesSdkLibLPw(serializer, pkg.getUsesSdkLibraries(), + pkg.getUsesSdkLibrariesVersionsMajor()); + writeUsesStaticLibLPw(serializer, pkg.getUsesStaticLibraries(), pkg.getUsesStaticLibrariesVersions()); @@ -2785,6 +2838,9 @@ public final class Settings implements Watchable, Snappable { serializer.attribute(null, "domainSetId", pkg.getDomainSetId().toString()); + writeUsesSdkLibLPw(serializer, pkg.getUsesSdkLibraries(), + pkg.getUsesSdkLibrariesVersionsMajor()); + writeUsesStaticLibLPw(serializer, pkg.getUsesStaticLibraries(), pkg.getUsesStaticLibrariesVersions()); @@ -3455,8 +3511,8 @@ public final class Settings implements Watchable, Snappable { UUID domainSetId = DomainVerificationManagerInternal.DISABLED_ID; PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr, secondaryCpuAbiStr, cpuAbiOverrideStr, - versionCode, pkgFlags, pkgPrivateFlags, 0 /*sharedUserId*/, null, null, null, - domainSetId); + versionCode, pkgFlags, pkgPrivateFlags, 0 /*sharedUserId*/, null, null, null, null, + null, domainSetId); long timeStamp = parser.getAttributeLongHex(null, "ft", 0); if (timeStamp == 0) { timeStamp = parser.getAttributeLong(null, "ts", 0); @@ -3484,6 +3540,8 @@ public final class Settings implements Watchable, Snappable { readInstallPermissionsLPr(parser, ps.getLegacyPermissionState(), users); } else if (parser.getName().equals(TAG_USES_STATIC_LIB)) { readUsesStaticLibLPw(parser, ps); + } else if (parser.getName().equals(TAG_USES_SDK_LIB)) { + readUsesSdkLibLPw(parser, ps); } else { PackageManagerService.reportSettingsProblem(Log.WARN, "Unknown element under <updated-package>: " + parser.getName()); @@ -3642,8 +3700,9 @@ public final class Settings implements Watchable, Snappable { packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags, pkgPrivateFlags, - null /*usesStaticLibraries*/, null /*usesStaticLibraryVersions*/, - null /*mimeGroups*/, domainSetId); + null /* usesSdkLibraries */, null /* usesSdkLibraryVersions */, + null /* usesStaticLibraries */, null /* usesStaticLibraryVersions */, + null /* mimeGroups */, domainSetId); if (PackageManagerService.DEBUG_SETTINGS) Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId=" + userId + " pkg=" + packageSetting); @@ -3662,9 +3721,11 @@ public final class Settings implements Watchable, Snappable { new File(codePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString, versionCode, pkgFlags, pkgPrivateFlags, sharedUserId, - null /*usesStaticLibraries*/, - null /*usesStaticLibraryVersions*/, - null /*mimeGroups*/, domainSetId); + null /* usesSdkLibraries */, + null /* usesSdkLibrariesVersions */, + null /* usesStaticLibraries */, + null /* usesStaticLibraryVersions */, + null /* mimeGroups */, domainSetId); packageSetting.setLastModifiedTime(timeStamp); packageSetting.setFirstInstallTime(firstInstallTime); packageSetting.setLastUpdateTime(lastUpdateTime); @@ -3793,6 +3854,8 @@ public final class Settings implements Watchable, Snappable { } } else if (tagName.equals(TAG_USES_STATIC_LIB)) { readUsesStaticLibLPw(parser, packageSetting); + } else if (tagName.equals(TAG_USES_SDK_LIB)) { + readUsesSdkLibLPw(parser, packageSetting); } else { PackageManagerService.reportSettingsProblem(Log.WARN, "Unknown element under <package>: " + parser.getName()); @@ -4581,6 +4644,13 @@ public final class Settings implements Watchable, Snappable { pw.print(" version:"); pw.println(pkg.getStaticSharedLibVersion()); } + if (pkg.getSdkLibName() != null) { + pw.print(prefix); pw.println(" SDK library:"); + pw.print(prefix); pw.print(" "); + pw.print("name:"); pw.print(pkg.getSdkLibName()); + pw.print(" versionMajor:"); pw.println(pkg.getSdkLibVersionMajor()); + } + List<String> usesLibraries = pkg.getUsesLibraries(); if (usesLibraries.size() > 0) { pw.print(prefix); pw.println(" usesLibraries:"); @@ -4600,6 +4670,17 @@ public final class Settings implements Watchable, Snappable { } } + List<String> usesSdkLibraries = pkg.getUsesSdkLibraries(); + long[] usesSdkLibrariesVersionsMajor = pkg.getUsesSdkLibrariesVersionsMajor(); + if (usesSdkLibraries.size() > 0) { + pw.print(prefix); pw.println(" usesSdkLibraries:"); + for (int i = 0, size = usesSdkLibraries.size(); i < size; ++i) { + pw.print(prefix); pw.print(" "); + pw.print(usesSdkLibraries.get(i)); pw.print(" version:"); + pw.println(usesSdkLibrariesVersionsMajor[i]); + } + } + List<String> usesOptionalLibraries = pkg.getUsesOptionalLibraries(); if (usesOptionalLibraries.size() > 0) { pw.print(prefix); pw.println(" usesOptionalLibraries:"); diff --git a/services/core/java/com/android/server/pm/SharedLibraryHelper.java b/services/core/java/com/android/server/pm/SharedLibraryHelper.java index 461fca1a817c..dd8fad0970fa 100644 --- a/services/core/java/com/android/server/pm/SharedLibraryHelper.java +++ b/services/core/java/com/android/server/pm/SharedLibraryHelper.java @@ -76,12 +76,15 @@ final class SharedLibraryHelper { Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingSharedLibraries) { // Let's used the parsed package as scanResult.pkgSetting may be null final ParsedPackage parsedPackage = scanResult.mRequest.mParsedPackage; - if (scanResult.mStaticSharedLibraryInfo == null + if (scanResult.mSdkSharedLibraryInfo == null && scanResult.mStaticSharedLibraryInfo == null && scanResult.mDynamicSharedLibraryInfos == null) { return null; } - // Any app can add new static shared libraries + // Any app can add new SDKs and static shared libraries. + if (scanResult.mSdkSharedLibraryInfo != null) { + return Collections.singletonList(scanResult.mSdkSharedLibraryInfo); + } if (scanResult.mStaticSharedLibraryInfo != null) { return Collections.singletonList(scanResult.mStaticSharedLibraryInfo); } @@ -181,41 +184,49 @@ final class SharedLibraryHelper { ArrayList<SharedLibraryInfo> usesLibraryInfos = null; if (!pkg.getUsesLibraries().isEmpty()) { usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesLibraries(), null, null, - pkg.getPackageName(), true, pkg.getTargetSdkVersion(), null, + pkg.getPackageName(), "shared", true, pkg.getTargetSdkVersion(), null, availablePackages, existingLibraries, newLibraries); } if (!pkg.getUsesStaticLibraries().isEmpty()) { usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesStaticLibraries(), pkg.getUsesStaticLibrariesVersions(), pkg.getUsesStaticLibrariesCertDigests(), - pkg.getPackageName(), true, pkg.getTargetSdkVersion(), usesLibraryInfos, - availablePackages, existingLibraries, newLibraries); + pkg.getPackageName(), "static shared", true, pkg.getTargetSdkVersion(), + usesLibraryInfos, availablePackages, existingLibraries, newLibraries); } if (!pkg.getUsesOptionalLibraries().isEmpty()) { - usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalLibraries(), - null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(), + usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalLibraries(), null, null, + pkg.getPackageName(), "shared", false, pkg.getTargetSdkVersion(), usesLibraryInfos, availablePackages, existingLibraries, newLibraries); } if (platformCompat.isChangeEnabledInternal(ENFORCE_NATIVE_SHARED_LIBRARY_DEPENDENCIES, pkg.getPackageName(), pkg.getTargetSdkVersion())) { if (!pkg.getUsesNativeLibraries().isEmpty()) { usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesNativeLibraries(), null, - null, pkg.getPackageName(), true, pkg.getTargetSdkVersion(), - usesLibraryInfos, availablePackages, existingLibraries, newLibraries); + null, pkg.getPackageName(), "native shared", true, + pkg.getTargetSdkVersion(), usesLibraryInfos, availablePackages, + existingLibraries, newLibraries); } if (!pkg.getUsesOptionalNativeLibraries().isEmpty()) { usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalNativeLibraries(), - null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(), - usesLibraryInfos, availablePackages, existingLibraries, newLibraries); + null, null, pkg.getPackageName(), "native shared", false, + pkg.getTargetSdkVersion(), usesLibraryInfos, availablePackages, + existingLibraries, newLibraries); } } + if (!pkg.getUsesSdkLibraries().isEmpty()) { + usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesSdkLibraries(), + pkg.getUsesSdkLibrariesVersionsMajor(), pkg.getUsesSdkLibrariesCertDigests(), + pkg.getPackageName(), "sdk", true, pkg.getTargetSdkVersion(), usesLibraryInfos, + availablePackages, existingLibraries, newLibraries); + } return usesLibraryInfos; } public static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos( @NonNull List<String> requestedLibraries, @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests, - @NonNull String packageName, boolean required, int targetSdk, - @Nullable ArrayList<SharedLibraryInfo> outUsedLibraries, + @NonNull String packageName, @NonNull String libraryType, boolean required, + int targetSdk, @Nullable ArrayList<SharedLibraryInfo> outUsedLibraries, @NonNull final Map<String, AndroidPackage> availablePackages, @NonNull final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> existingLibraries, @Nullable final Map<String, WatchedLongSparseArray<SharedLibraryInfo>> newLibraries) @@ -230,18 +241,17 @@ final class SharedLibraryHelper { if (libraryInfo == null) { if (required) { throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, - "Package " + packageName + " requires unavailable shared library " - + libName + "; failing!"); + "Package " + packageName + " requires unavailable " + libraryType + + " library " + libName + "; failing!"); } else if (DEBUG_SHARED_LIBRARIES) { - Slog.i(TAG, "Package " + packageName - + " desires unavailable shared library " - + libName + "; ignoring!"); + Slog.i(TAG, "Package " + packageName + " desires unavailable " + libraryType + + " library " + libName + "; ignoring!"); } } else { if (requiredVersions != null && requiredCertDigests != null) { if (libraryInfo.getLongVersion() != requiredVersions[i]) { throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, - "Package " + packageName + " requires unavailable static shared" + "Package " + packageName + " requires unavailable " + libraryType + " library " + libName + " version " + libraryInfo.getLongVersion() + "; failing!"); } @@ -249,7 +259,7 @@ final class SharedLibraryHelper { SigningDetails libPkg = pkg == null ? null : pkg.getSigningDetails(); if (libPkg == null) { throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, - "Package " + packageName + " requires unavailable static shared" + "Package " + packageName + " requires unavailable " + libraryType + " library; failing!"); } final String[] expectedCertDigests = requiredCertDigests[i]; @@ -267,8 +277,8 @@ final class SharedLibraryHelper { // Therefore, the size check is safe to make. if (expectedCertDigests.length != libCertDigests.length) { throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, - "Package " + packageName + " requires differently signed" - + " static shared library; failing!"); + "Package " + packageName + " requires differently signed " + + libraryType + " library; failing!"); } // Use a predictable order as signature order may vary @@ -280,8 +290,8 @@ final class SharedLibraryHelper { if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) { throw new PackageManagerException( INSTALL_FAILED_MISSING_SHARED_LIBRARY, - "Package " + packageName + " requires differently signed" - + " static shared library; failing!"); + "Package " + packageName + " requires differently signed " + + libraryType + " library; failing!"); } } } else { @@ -290,10 +300,9 @@ final class SharedLibraryHelper { byte[] digestBytes = HexEncoding.decode( expectedCertDigests[0], false /* allowSingleChar */); if (!libPkg.hasSha256Certificate(digestBytes)) { - throw new PackageManagerException( - INSTALL_FAILED_MISSING_SHARED_LIBRARY, - "Package " + packageName + " requires differently signed" - + " static shared library; failing!"); + throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, + "Package " + packageName + " requires differently signed " + + libraryType + " library; failing!"); } } } diff --git a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java index 32b1e5dbd3db..8b2c3a12eda7 100644 --- a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java +++ b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java @@ -87,6 +87,17 @@ public class AndroidPackageUtils { return paths; } + public static SharedLibraryInfo createSharedLibraryForSdk(AndroidPackage pkg) { + return new SharedLibraryInfo(null, pkg.getPackageName(), + AndroidPackageUtils.getAllCodePaths(pkg), + pkg.getSdkLibName(), + pkg.getSdkLibVersionMajor(), + SharedLibraryInfo.TYPE_SDK, + new VersionedPackage(pkg.getManifestPackageName(), + pkg.getLongVersionCode()), + null, null, false /* isNative */); + } + public static SharedLibraryInfo createSharedLibraryForStatic(AndroidPackage pkg) { return new SharedLibraryInfo(null, pkg.getPackageName(), AndroidPackageUtils.getAllCodePaths(pkg), @@ -218,7 +229,8 @@ public class AndroidPackageUtils { public static boolean isLibrary(AndroidPackage pkg) { // TODO(b/135203078): Can parsing just enforce these always match? - return pkg.getStaticSharedLibName() != null || !pkg.getLibraryNames().isEmpty(); + return pkg.getSdkLibName() != null || pkg.getStaticSharedLibName() != null + || !pkg.getLibraryNames().isEmpty(); } public static int getHiddenApiEnforcementPolicy(AndroidPackage pkg, diff --git a/services/core/java/com/android/server/pm/pkg/PackageState.java b/services/core/java/com/android/server/pm/pkg/PackageState.java index 82edce69858b..34575e081ca8 100644 --- a/services/core/java/com/android/server/pm/pkg/PackageState.java +++ b/services/core/java/com/android/server/pm/pkg/PackageState.java @@ -27,7 +27,6 @@ import android.content.pm.SharedLibraryInfo; import android.content.pm.SigningInfo; import android.util.SparseArray; -import com.android.internal.R; import com.android.server.pm.PackageSetting; import com.android.server.pm.Settings; @@ -206,6 +205,18 @@ public interface PackageState { List<SharedLibraryInfo> getUsesLibraryInfos(); /** + * @see R.styleable#AndroidManifestUsesSdkLibrary + */ + @NonNull + String[] getUsesSdkLibraries(); + + /** + * @see R.styleable#AndroidManifestUsesSdkLibrary_versionMajor + */ + @NonNull + long[] getUsesSdkLibrariesVersionsMajor(); + + /** * @see R.styleable#AndroidManifestUsesStaticLibrary */ @NonNull diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java b/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java index 46d32b9f3954..f5e498d2fc9a 100644 --- a/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java +++ b/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java @@ -130,6 +130,10 @@ public class PackageStateImpl implements PackageState { @Nullable private final Integer mSharedUserId; @NonNull + private final String[] mUsesSdkLibraries; + @NonNull + private final long[] mUsesSdkLibrariesVersionsMajor; + @NonNull private final String[] mUsesStaticLibraries; @NonNull private final long[] mUsesStaticLibrariesVersions; @@ -171,6 +175,8 @@ public class PackageStateImpl implements PackageState { mPrimaryCpuAbi = pkgState.getPrimaryCpuAbi(); mSecondaryCpuAbi = pkgState.getSecondaryCpuAbi(); mSharedUserId = pkgState.getSharedUserId(); + mUsesSdkLibraries = pkgState.getUsesSdkLibraries(); + mUsesSdkLibrariesVersionsMajor = pkgState.getUsesSdkLibrariesVersionsMajor(); mUsesStaticLibraries = pkgState.getUsesStaticLibraries(); mUsesStaticLibrariesVersions = pkgState.getUsesStaticLibrariesVersions(); mUsesLibraryInfos = pkgState.getUsesLibraryInfos(); @@ -262,6 +268,11 @@ public class PackageStateImpl implements PackageState { return getBoolean(Booleans.VENDOR); } + @Override + public long getVersionCode() { + return mLongVersionCode; + } + /** * @hide */ @@ -500,10 +511,10 @@ public class PackageStateImpl implements PackageState { } @DataClass.Generated( - time = 1633375703010L, + time = 1637977288540L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java", - inputSignatures = "private int mBooleans\nprivate final long mCeDataInode\nprivate final @android.annotation.NonNull java.util.Set<java.lang.String> mDisabledComponents\nprivate final @android.content.pm.PackageManager.DistractionRestriction int mDistractionFlags\nprivate final @android.annotation.NonNull java.util.Set<java.lang.String> mEnabledComponents\nprivate final int mEnabledState\nprivate final @android.annotation.Nullable java.lang.String mHarmfulAppWarning\nprivate final @android.content.pm.PackageManager.InstallReason int mInstallReason\nprivate final @android.annotation.Nullable java.lang.String mLastDisableAppCaller\nprivate final @android.annotation.NonNull android.content.pm.overlay.OverlayPaths mOverlayPaths\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,android.content.pm.overlay.OverlayPaths> mSharedLibraryOverlayPaths\nprivate final @android.content.pm.PackageManager.UninstallReason int mUninstallReason\nprivate final @android.annotation.Nullable java.lang.String mSplashScreenTheme\npublic static android.content.pm.pkg.PackageUserState copy(android.content.pm.pkg.PackageUserState)\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\npublic @java.lang.Override boolean isHidden()\npublic @java.lang.Override boolean isInstalled()\npublic @java.lang.Override boolean isInstantApp()\npublic @java.lang.Override boolean isNotLaunched()\npublic @java.lang.Override boolean isStopped()\npublic @java.lang.Override boolean isSuspended()\npublic @java.lang.Override boolean isVirtualPreload()\npublic @java.lang.Override boolean isComponentEnabled(java.lang.String)\npublic @java.lang.Override boolean isComponentDisabled(java.lang.String)\npublic @java.lang.Override android.content.pm.overlay.OverlayPaths getAllOverlayPaths()\nclass UserStateImpl extends java.lang.Object implements [android.content.pm.pkg.PackageUserState]\nprivate static final int HIDDEN\nprivate static final int INSTALLED\nprivate static final int INSTANT_APP\nprivate static final int NOT_LAUNCHED\nprivate static final int STOPPED\nprivate static final int SUSPENDED\nprivate static final int VIRTUAL_PRELOAD\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false)") + inputSignatures = "private int mBooleans\nprivate final long mCeDataInode\nprivate final @android.annotation.NonNull java.util.Set<java.lang.String> mDisabledComponents\nprivate final @android.content.pm.PackageManager.DistractionRestriction int mDistractionFlags\nprivate final @android.annotation.NonNull java.util.Set<java.lang.String> mEnabledComponents\nprivate final int mEnabledState\nprivate final @android.annotation.Nullable java.lang.String mHarmfulAppWarning\nprivate final @android.content.pm.PackageManager.InstallReason int mInstallReason\nprivate final @android.annotation.Nullable java.lang.String mLastDisableAppCaller\nprivate final @android.annotation.NonNull android.content.pm.overlay.OverlayPaths mOverlayPaths\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,android.content.pm.overlay.OverlayPaths> mSharedLibraryOverlayPaths\nprivate final @android.content.pm.PackageManager.UninstallReason int mUninstallReason\nprivate final @android.annotation.Nullable java.lang.String mSplashScreenTheme\npublic static com.android.server.pm.pkg.PackageUserState copy(com.android.server.pm.pkg.PackageUserState)\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\npublic @java.lang.Override boolean isHidden()\npublic @java.lang.Override boolean isInstalled()\npublic @java.lang.Override boolean isInstantApp()\npublic @java.lang.Override boolean isNotLaunched()\npublic @java.lang.Override boolean isStopped()\npublic @java.lang.Override boolean isSuspended()\npublic @java.lang.Override boolean isVirtualPreload()\npublic @java.lang.Override boolean isComponentEnabled(java.lang.String)\npublic @java.lang.Override boolean isComponentDisabled(java.lang.String)\npublic @java.lang.Override android.content.pm.overlay.OverlayPaths getAllOverlayPaths()\nclass UserStateImpl extends java.lang.Object implements [com.android.server.pm.pkg.PackageUserState]\nprivate static final int HIDDEN\nprivate static final int INSTALLED\nprivate static final int INSTANT_APP\nprivate static final int NOT_LAUNCHED\nprivate static final int STOPPED\nprivate static final int SUSPENDED\nprivate static final int VIRTUAL_PRELOAD\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false)") @Deprecated private void __metadata() {} @@ -579,7 +590,7 @@ public class PackageStateImpl implements PackageState { } @DataClass.Generated.Member - public long getVersionCode() { + public long getLongVersionCode() { return mLongVersionCode; } @@ -609,6 +620,16 @@ public class PackageStateImpl implements PackageState { } @DataClass.Generated.Member + public @NonNull String[] getUsesSdkLibraries() { + return mUsesSdkLibraries; + } + + @DataClass.Generated.Member + public @NonNull long[] getUsesSdkLibrariesVersionsMajor() { + return mUsesSdkLibrariesVersionsMajor; + } + + @DataClass.Generated.Member public @NonNull String[] getUsesStaticLibraries() { return mUsesStaticLibraries; } @@ -650,10 +671,10 @@ public class PackageStateImpl implements PackageState { } @DataClass.Generated( - time = 1633375703038L, + time = 1637977288579L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java", - inputSignatures = "private int mBooleans\nprivate final @android.annotation.Nullable com.android.server.pm.pkg.AndroidPackageApi mAndroidPackage\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mVolumeUuid\nprivate final int mAppId\nprivate final int mCategoryOverride\nprivate final @android.annotation.Nullable java.lang.String mCpuAbiOverride\nprivate final long mFirstInstallTime\nprivate final long mLastModifiedTime\nprivate final long mLastUpdateTime\nprivate final long mLongVersionCode\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,java.util.Set<java.lang.String>> mMimeGroups\nprivate final @android.annotation.NonNull java.io.File mPath\nprivate final @android.annotation.Nullable java.lang.String mPrimaryCpuAbi\nprivate final @android.annotation.Nullable java.lang.String mSecondaryCpuAbi\nprivate final @android.annotation.Nullable java.lang.Integer mSharedUserId\nprivate final @android.annotation.NonNull java.lang.String[] mUsesStaticLibraries\nprivate final @android.annotation.NonNull long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mUsesLibraryInfos\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesLibraryFiles\nprivate final @android.annotation.NonNull long[] mLastPackageUsageTime\nprivate final @android.annotation.NonNull android.content.pm.SigningInfo mSigningInfo\nprivate final @android.annotation.NonNull android.util.SparseArray<android.content.pm.pkg.PackageUserState> mUserStates\npublic static com.android.server.pm.pkg.PackageState copy(com.android.server.pm.PackageSetting)\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\npublic @java.lang.Override boolean isExternalStorage()\npublic @java.lang.Override boolean isForceQueryableOverride()\npublic @java.lang.Override boolean isHiddenUntilInstalled()\npublic @java.lang.Override boolean isInstallPermissionsFixed()\npublic @java.lang.Override boolean isOdm()\npublic @java.lang.Override boolean isOem()\npublic @java.lang.Override boolean isPrivileged()\npublic @java.lang.Override boolean isProduct()\npublic @java.lang.Override boolean isRequiredForSystemUser()\npublic @java.lang.Override boolean isSystem()\npublic @java.lang.Override boolean isSystemExt()\npublic @java.lang.Override boolean isUpdateAvailable()\npublic @java.lang.Override boolean isUpdatedSystemApp()\npublic @java.lang.Override boolean isVendor()\nclass PackageStateImpl extends java.lang.Object implements [com.android.server.pm.pkg.PackageState]\nprivate static final int SYSTEM\nprivate static final int EXTERNAL_STORAGE\nprivate static final int PRIVILEGED\nprivate static final int OEM\nprivate static final int VENDOR\nprivate static final int PRODUCT\nprivate static final int SYSTEM_EXT\nprivate static final int REQUIRED_FOR_SYSTEM_USER\nprivate static final int ODM\nprivate static final int FORCE_QUERYABLE_OVERRIDE\nprivate static final int HIDDEN_UNTIL_INSTALLED\nprivate static final int INSTALL_PERMISSIONS_FIXED\nprivate static final int UPDATE_AVAILABLE\nprivate static final int UPDATED_SYSTEM_APP\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false)") + inputSignatures = "private int mBooleans\nprivate final @android.annotation.Nullable com.android.server.pm.pkg.AndroidPackageApi mAndroidPackage\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mVolumeUuid\nprivate final int mAppId\nprivate final int mCategoryOverride\nprivate final @android.annotation.Nullable java.lang.String mCpuAbiOverride\nprivate final long mFirstInstallTime\nprivate final long mLastModifiedTime\nprivate final long mLastUpdateTime\nprivate final long mLongVersionCode\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,java.util.Set<java.lang.String>> mMimeGroups\nprivate final @android.annotation.NonNull java.io.File mPath\nprivate final @android.annotation.Nullable java.lang.String mPrimaryCpuAbi\nprivate final @android.annotation.Nullable java.lang.String mSecondaryCpuAbi\nprivate final @android.annotation.Nullable java.lang.Integer mSharedUserId\nprivate final @android.annotation.NonNull java.lang.String[] mUsesSdkLibraries\nprivate final @android.annotation.NonNull long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.NonNull java.lang.String[] mUsesStaticLibraries\nprivate final @android.annotation.NonNull long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> mUsesLibraryInfos\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesLibraryFiles\nprivate final @android.annotation.NonNull long[] mLastPackageUsageTime\nprivate final @android.annotation.NonNull android.content.pm.SigningInfo mSigningInfo\nprivate final @android.annotation.NonNull android.util.SparseArray<com.android.server.pm.pkg.PackageUserState> mUserStates\npublic static com.android.server.pm.pkg.PackageState copy(com.android.server.pm.pkg.PackageStateInternal)\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\npublic @java.lang.Override boolean isExternalStorage()\npublic @java.lang.Override boolean isForceQueryableOverride()\npublic @java.lang.Override boolean isHiddenUntilInstalled()\npublic @java.lang.Override boolean isInstallPermissionsFixed()\npublic @java.lang.Override boolean isOdm()\npublic @java.lang.Override boolean isOem()\npublic @java.lang.Override boolean isPrivileged()\npublic @java.lang.Override boolean isProduct()\npublic @java.lang.Override boolean isRequiredForSystemUser()\npublic @java.lang.Override boolean isSystem()\npublic @java.lang.Override boolean isSystemExt()\npublic @java.lang.Override boolean isUpdateAvailable()\npublic @java.lang.Override boolean isUpdatedSystemApp()\npublic @java.lang.Override boolean isVendor()\npublic @java.lang.Override long getVersionCode()\nclass PackageStateImpl extends java.lang.Object implements [com.android.server.pm.pkg.PackageState]\nprivate static final int SYSTEM\nprivate static final int EXTERNAL_STORAGE\nprivate static final int PRIVILEGED\nprivate static final int OEM\nprivate static final int VENDOR\nprivate static final int PRODUCT\nprivate static final int SYSTEM_EXT\nprivate static final int REQUIRED_FOR_SYSTEM_USER\nprivate static final int ODM\nprivate static final int FORCE_QUERYABLE_OVERRIDE\nprivate static final int HIDDEN_UNTIL_INSTALLED\nprivate static final int INSTALL_PERMISSIONS_FIXED\nprivate static final int UPDATE_AVAILABLE\nprivate static final int UPDATED_SYSTEM_APP\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false)") @Deprecated private void __metadata() {} diff --git a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt index 9d86081bcf23..4b12fd41f747 100644 --- a/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt +++ b/services/tests/PackageManagerComponentOverrideTests/src/com/android/server/pm/test/override/PackageManagerComponentLabelIconOverrideTest.kt @@ -274,7 +274,7 @@ class PackageManagerComponentLabelIconOverrideTest { private fun makePkgSetting(pkgName: String) = spy( PackageSetting( pkgName, null, File("/test"), - null, null, null, null, 0, 0, 0, 0, null, null, null, + null, null, null, null, 0, 0, 0, 0, null, null, null, null, null, UUID.fromString("3f9d52b7-d7b4-406a-a1da-d9f19984c72c") ) ) { diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt index dc93e53a0d24..4a35fdf2b508 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt @@ -106,6 +106,16 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag "setSplitCodePaths", "setSplitClassLoaderName", "setSplitHasCode", + // Tested through addUsesSdkLibrary + "addUsesSdkLibrary", + "getUsesSdkLibraries", + "getUsesSdkLibrariesVersionsMajor", + "getUsesSdkLibrariesCertDigests", + // Tested through addUsesStaticLibrary + "addUsesStaticLibrary", + "getUsesStaticLibraries", + "getUsesStaticLibrariesVersions", + "getUsesStaticLibrariesCertDigests" ) override val baseParams = listOf( @@ -157,6 +167,8 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag AndroidPackage::getSecondaryNativeLibraryDir, AndroidPackage::getSharedUserId, AndroidPackage::getSharedUserLabel, + AndroidPackage::getSdkLibName, + AndroidPackage::getSdkLibVersionMajor, AndroidPackage::getStaticSharedLibName, AndroidPackage::getStaticSharedLibVersion, AndroidPackage::getTargetSandboxVersion, @@ -210,6 +222,7 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag AndroidPackage::isResizeableActivityViaSdkVersion, AndroidPackage::isRestoreAnyVersion, AndroidPackage::isSignedWithPlatformKey, + AndroidPackage::isSdkLibrary, AndroidPackage::isStaticSharedLibrary, AndroidPackage::isStub, AndroidPackage::isSupportsRtl, @@ -228,7 +241,7 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag AndroidPackage::getMinAspectRatio, AndroidPackage::hasPreserveLegacyExternalStorage, AndroidPackage::hasRequestForegroundServiceExemption, - AndroidPackage::hasRequestRawExternalStorageAccess, + AndroidPackage::hasRequestRawExternalStorageAccess ) override fun extraParams() = listOf( @@ -254,13 +267,6 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag adder(AndroidPackage::getUsesNativeLibraries, "testUsesNativeLibrary"), adder(AndroidPackage::getUsesOptionalLibraries, "testUsesOptionalLibrary"), adder(AndroidPackage::getUsesOptionalNativeLibraries, "testUsesOptionalNativeLibrary"), - adder(AndroidPackage::getUsesStaticLibraries, "testUsesStaticLibrary"), - getSetByValue( - AndroidPackage::getUsesStaticLibrariesVersions, - PackageImpl::addUsesStaticLibraryVersion, - (testCounter++).toLong(), - transformGet = { it?.singleOrNull() } - ), getSetByValue( AndroidPackage::areAttributionsUserVisible, ParsingPackage::setAttributionsAreUserVisible, @@ -290,7 +296,7 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag AndroidPackage::getKeySetMapping, PackageImpl::addKeySet, "testKeySetName" to testKey(), - transformGet = { "testKeySetName" to it["testKeySetName"]?.singleOrNull() }, + transformGet = { "testKeySetName" to it["testKeySetName"]?.singleOrNull() } ), getSetByValue( AndroidPackage::getPermissionGroups, @@ -315,7 +321,7 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag { it.first }, { it.second.intentFilter.schemesIterator().asSequence().singleOrNull() }, { it.second.intentFilter.authoritiesIterator().asSequence() - .singleOrNull()?.host }, + .singleOrNull()?.host } ) } ), @@ -324,7 +330,7 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag PackageImpl::addQueriesIntent, Intent(Intent.ACTION_VIEW, Uri.parse("https://test.pm.server.android.com")), transformGet = { it.singleOrNull() }, - compare = { first, second -> first?.filterEquals(second) }, + compare = { first, second -> first?.filterEquals(second) } ), getSetByValue( AndroidPackage::getRestrictUpdateHash, @@ -347,13 +353,6 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag } ), getSetByValue( - AndroidPackage::getUsesStaticLibrariesCertDigests, - PackageImpl::addUsesStaticLibraryCertDigests, - arrayOf("testCertDigest"), - transformGet = { it?.singleOrNull() }, - compare = Array<String?>?::contentEquals - ), - getSetByValue( AndroidPackage::getActivities, PackageImpl::addActivity, "TestActivityName", @@ -440,7 +439,7 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag first, second, { it.size() }, { it.keyAt(0) }, - { it.valueAt(0) }, + { it.valueAt(0) } ) } ), @@ -451,7 +450,7 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag compare = { first, second -> equalBy( first, second, - { it["testProcess"]?.name }, + { it["testProcess"]?.name } ) } ), @@ -471,10 +470,10 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag PackageManager.Property::getName, PackageManager.Property::getClassName, PackageManager.Property::getPackageName, - PackageManager.Property::getString, + PackageManager.Property::getString ) } - ), + ) ) override fun initialObject() = PackageImpl.forParsing( @@ -518,6 +517,9 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag .setSplitClassLoaderName(0, "testSplitClassLoaderNameZero") .setSplitClassLoaderName(1, "testSplitClassLoaderNameOne") + .addUsesSdkLibrary("testSdk", 2L, arrayOf("testCertDigest1")) + .addUsesStaticLibrary("testStatic", 3L, arrayOf("testCertDigest2")) + override fun extraAssertions(before: Parcelable, after: Parcelable) { super.extraAssertions(before, after) after as PackageImpl @@ -558,6 +560,18 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag expect.that(it.get(0)).asList().containsExactly(-1) expect.that(it.get(1)).asList().containsExactly(0) } + + expect.that(after.usesSdkLibraries).containsExactly("testSdk") + expect.that(after.usesSdkLibrariesVersionsMajor).asList().containsExactly(2L) + expect.that(after.usesSdkLibrariesCertDigests!!.size).isEqualTo(1) + expect.that(after.usesSdkLibrariesCertDigests!![0]).asList() + .containsExactly("testCertDigest1") + + expect.that(after.usesStaticLibraries).containsExactly("testStatic") + expect.that(after.usesStaticLibrariesVersions).asList().containsExactly(3L) + expect.that(after.usesStaticLibrariesCertDigests!!.size).isEqualTo(1) + expect.that(after.usesStaticLibrariesCertDigests!![0]).asList() + .containsExactly("testCertDigest2") } private fun testKey() = KeyPairGenerator.getInstance("RSA") diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt index 0e5640aa85dd..ae5984a41770 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt @@ -150,7 +150,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) { } whenever(mocks.settings.addPackageLPw(nullable(), nullable(), nullable(), nullable(), nullable(), nullable(), nullable(), nullable(), nullable(), nullable(), nullable(), - nullable(), nullable(), nullable(), nullable())) { + nullable(), nullable(), nullable(), nullable(), nullable(), nullable())) { val name: String = getArgument(0) val pendingAdd = mPendingPackageAdds.firstOrNull { it.first == name } ?: return@whenever null diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java index a9a3469d52cc..6c9f8fee25b0 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -498,6 +498,71 @@ public class PackageManagerSettingsTests { } @Test + public void testWriteReadUsesSdkLibraries() { + final Settings settingsUnderTest = makeSettings(); + final PackageSetting ps1 = createPackageSetting(PACKAGE_NAME_1); + ps1.setAppId(Process.FIRST_APPLICATION_UID); + ps1.setPkg(((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME_1).hideAsParsed()) + .setUid(ps1.getAppId()) + .setSystem(true) + .hideAsFinal()); + final PackageSetting ps2 = createPackageSetting(PACKAGE_NAME_2); + ps2.setAppId(Process.FIRST_APPLICATION_UID + 1); + ps2.setPkg(((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME_2).hideAsParsed()) + .setUid(ps2.getAppId()) + .hideAsFinal()); + + ps1.setUsesSdkLibraries(new String[] { "com.example.sdk.one" }); + ps1.setUsesSdkLibrariesVersionsMajor(new long[] { 12 }); + ps1.setFlags(ps1.getFlags() | ApplicationInfo.FLAG_SYSTEM); + settingsUnderTest.mPackages.put(PACKAGE_NAME_1, ps1); + assertThat(settingsUnderTest.disableSystemPackageLPw(PACKAGE_NAME_1, false), is(true)); + + ps2.setUsesSdkLibraries(new String[] { "com.example.sdk.two" }); + ps2.setUsesSdkLibrariesVersionsMajor(new long[] { 34 }); + settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2); + + settingsUnderTest.writeLPr(); + + settingsUnderTest.mPackages.clear(); + settingsUnderTest.mDisabledSysPackages.clear(); + + assertThat(settingsUnderTest.readLPw(createFakeUsers()), is(true)); + + PackageSetting readPs1 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_1); + PackageSetting readPs2 = settingsUnderTest.getPackageLPr(PACKAGE_NAME_2); + + Truth.assertThat(readPs1).isNotNull(); + Truth.assertThat(readPs1.getUsesSdkLibraries()).isNotNull(); + Truth.assertThat(readPs1.getUsesSdkLibrariesVersionsMajor()).isNotNull(); + Truth.assertThat(readPs2).isNotNull(); + Truth.assertThat(readPs2.getUsesSdkLibraries()).isNotNull(); + Truth.assertThat(readPs2.getUsesSdkLibrariesVersionsMajor()).isNotNull(); + + List<Long> ps1VersionsAsList = new ArrayList<>(); + for (long version : ps1.getUsesSdkLibrariesVersionsMajor()) { + ps1VersionsAsList.add(version); + } + + List<Long> ps2VersionsAsList = new ArrayList<>(); + for (long version : ps2.getUsesSdkLibrariesVersionsMajor()) { + ps2VersionsAsList.add(version); + } + + Truth.assertThat(readPs1.getUsesSdkLibraries()).asList() + .containsExactlyElementsIn(ps1.getUsesSdkLibraries()).inOrder(); + + Truth.assertThat(readPs1.getUsesSdkLibrariesVersionsMajor()).asList() + .containsExactlyElementsIn(ps1VersionsAsList).inOrder(); + + Truth.assertThat(readPs2.getUsesSdkLibraries()).asList() + .containsExactlyElementsIn(ps2.getUsesSdkLibraries()).inOrder(); + + Truth.assertThat(readPs2.getUsesSdkLibrariesVersionsMajor()).asList() + .containsExactlyElementsIn(ps2VersionsAsList).inOrder(); + } + + @Test public void testPackageRestrictionsDistractionFlagsDefault() { final PackageSetting defaultSetting = createPackageSetting(PACKAGE_NAME_1); assertThat(defaultSetting.getDistractionFlags(0), is(PackageManager.RESTRICTION_NONE)); @@ -571,6 +636,8 @@ public class PackageManagerSettingsTests { ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_HAS_CODE, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED|ApplicationInfo.PRIVATE_FLAG_HIDDEN, 0, + null /*usesSdkLibraries*/, + null /*usesSdkLibrariesVersions*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/, @@ -593,6 +660,8 @@ public class PackageManagerSettingsTests { ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_HAS_CODE, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED|ApplicationInfo.PRIVATE_FLAG_HIDDEN, 0, + null /*usesSdkLibraries*/, + null /*usesSdkLibrariesVersions*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/, @@ -609,6 +678,8 @@ public class PackageManagerSettingsTests { 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, 0, + null /*usesSdkLibraries*/, + null /*usesSdkLibrariesVersions*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/, @@ -637,6 +708,8 @@ public class PackageManagerSettingsTests { 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, UserManagerService.getInstance(), + null /*usesSdkLibraries*/, + null /*usesSdkLibrariesVersions*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/, @@ -671,6 +744,8 @@ public class PackageManagerSettingsTests { ApplicationInfo.FLAG_SYSTEM /*pkgFlags*/, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED /*pkgPrivateFlags*/, UserManagerService.getInstance(), + null /*usesSdkLibraries*/, + null /*usesSdkLibrariesVersions*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/, @@ -708,6 +783,8 @@ public class PackageManagerSettingsTests { 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, UserManagerService.getInstance(), + null /*usesSdkLibraries*/, + null /*usesSdkLibrariesVersions*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/, @@ -741,6 +818,8 @@ public class PackageManagerSettingsTests { false /*instantApp*/, false /*virtualPreload*/, UserManagerService.getInstance(), + null /*usesSdkLibraries*/, + null /*usesSdkLibrariesVersions*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/, @@ -780,6 +859,8 @@ public class PackageManagerSettingsTests { false /*instantApp*/, false /*virtualPreload*/, UserManagerService.getInstance(), + null /*usesSdkLibraries*/, + null /*usesSdkLibrariesVersions*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/, @@ -822,6 +903,8 @@ public class PackageManagerSettingsTests { false /*instantApp*/, false /*virtualPreload*/, UserManagerService.getInstance(), + null /*usesSdkLibraries*/, + null /*usesSdkLibrariesVersions*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/, @@ -864,6 +947,8 @@ public class PackageManagerSettingsTests { false /*instantApp*/, false /*virtualPreload*/, UserManagerService.getInstance(), + null /*usesSdkLibraries*/, + null /*usesSdkLibrariesVersions*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/, @@ -971,6 +1056,25 @@ public class PackageManagerSettingsTests { assertThat(countDownLatch.getCount(), is(1L)); } + @Test + public void testSetPkgStateLibraryFiles_addNewSdks() { + final PackageSetting packageSetting = createPackageSetting("com.foo"); + final CountDownLatch countDownLatch = new CountDownLatch(1); + packageSetting.registerObserver(new Watcher() { + @Override + public void onChange(Watchable what) { + countDownLatch.countDown(); + } + }); + + final List<String> files = new ArrayList<>(); + files.add("com.sdk1_123"); + files.add("com.sdk9_876"); + packageSetting.setUsesSdkLibraries(files.toArray(new String[files.size()])); + + assertThat(countDownLatch.getCount(), is(0L)); + } + private <T> void assertArrayEquals(T[] a, T[] b) { assertTrue("Expected: " + Arrays.toString(a) + ", actual: " + Arrays.toString(b), Arrays.equals(a, b)); @@ -1090,6 +1194,8 @@ public class PackageManagerSettingsTests { pkgFlags, 0 /*privateFlags*/, sharedUserId, + null /*usesSdkLibraries*/, + null /*usesSdkLibrariesVersions*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/, @@ -1109,6 +1215,8 @@ public class PackageManagerSettingsTests { 0, 0 /*privateFlags*/, 0, + null /*usesSdkLibraries*/, + null /*usesSdkLibrariesVersions*/, null /*usesStaticLibraries*/, null /*usesStaticLibrariesVersions*/, null /*mimeGroups*/, diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java index fb092d2d244b..11bac4547fde 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java @@ -932,11 +932,12 @@ public class PackageParserTest { .addUsesPermission(new ParsedUsesPermissionImpl("foo7", 0)) .addImplicitPermission("foo25") .addProtectedBroadcast("foo8") + .setSdkLibName("sdk12") + .setSdkLibVersionMajor(42) + .addUsesSdkLibrary("sdk23", 200, new String[]{"digest2"}) .setStaticSharedLibName("foo23") .setStaticSharedLibVersion(100) - .addUsesStaticLibrary("foo23") - .addUsesStaticLibraryCertDigests(new String[]{"digest"}) - .addUsesStaticLibraryVersion(100) + .addUsesStaticLibrary("foo23", 100, new String[]{"digest"}) .addLibraryName("foo10") .addUsesLibrary("foo11") .addUsesOptionalLibrary("foo12") diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java index 21460705fd52..94d8358b4a43 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java @@ -44,8 +44,6 @@ public class PackageSettingBuilder { private SparseArray<PackageUserStateImpl> mUserStates = new SparseArray<>(); private AndroidPackage mPkg; private InstallSource mInstallSource; - private String[] mUsesStaticLibraries; - private long[] mUsesStaticLibrariesVersions; private Map<String, Set<String>> mMimeGroups; private SigningDetails mSigningDetails; private UUID mDomainSetId = UUID.randomUUID(); @@ -116,17 +114,6 @@ public class PackageSettingBuilder { return this; } - public PackageSettingBuilder setUsesStaticLibraries(String[] usesStaticLibraries) { - this.mUsesStaticLibraries = usesStaticLibraries; - return this; - } - - public PackageSettingBuilder setUsesStaticLibrariesVersions( - long[] usesStaticLibrariesVersions) { - this.mUsesStaticLibrariesVersions = usesStaticLibrariesVersions; - return this; - } - public PackageSettingBuilder setMimeGroups(Map<String, Set<String>> mimeGroups) { this.mMimeGroups = mimeGroups; return this; @@ -173,8 +160,9 @@ public class PackageSettingBuilder { final PackageSetting packageSetting = new PackageSetting(mName, mRealName, new File(mCodePath), mLegacyNativeLibraryPathString, mPrimaryCpuAbiString, mSecondaryCpuAbiString, mCpuAbiOverrideString, mPVersionCode, mPkgFlags, - mPrivateFlags, mSharedUserId, mUsesStaticLibraries, mUsesStaticLibrariesVersions, - mMimeGroups, mDomainSetId); + mPrivateFlags, mSharedUserId, null /* usesSdkLibraries */, + null /* usesSdkLibrariesVersions */, null /* usesStaticLibraries */, + null /* usesStaticLibrariesVersions */, mMimeGroups, mDomainSetId); packageSetting.setSignatures(mSigningDetails != null ? new PackageSignatures(mSigningDetails) : new PackageSignatures()); diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java index cfdbb5b7b30b..71d5b77306a4 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java @@ -17,6 +17,7 @@ package com.android.server.pm; import static android.content.pm.SharedLibraryInfo.TYPE_DYNAMIC; +import static android.content.pm.SharedLibraryInfo.TYPE_SDK; import static android.content.pm.SharedLibraryInfo.TYPE_STATIC; import static android.content.pm.SharedLibraryInfo.VERSION_UNDEFINED; @@ -238,6 +239,37 @@ public class ScanTests { } @Test + public void installSdkLibrary() throws Exception { + final ParsedPackage pkg = ((ParsedPackage) createBasicPackage("ogl.sdk_123") + .setSdkLibName("ogl.sdk") + .setSdkLibVersionMajor(123) + .hideAsParsed()) + .setPackageName("ogl.sdk_123") + .setVersionCodeMajor(5) + .setVersionCode(678) + .setBaseApkPath("/some/path.apk") + .setSplitCodePaths(new String[] {"/some/other/path.apk"}); + + final ScanRequest scanRequest = new ScanRequestBuilder(pkg) + .setUser(UserHandle.of(0)).build(); + + final ScanResult scanResult = executeScan(scanRequest); + + assertThat(scanResult.mSdkSharedLibraryInfo.getPackageName(), is("ogl.sdk_123")); + assertThat(scanResult.mSdkSharedLibraryInfo.getName(), is("ogl.sdk")); + assertThat(scanResult.mSdkSharedLibraryInfo.getLongVersion(), is(123L)); + assertThat(scanResult.mSdkSharedLibraryInfo.getType(), is(TYPE_SDK)); + assertThat(scanResult.mSdkSharedLibraryInfo.getDeclaringPackage().getPackageName(), + is("ogl.sdk_123")); + assertThat(scanResult.mSdkSharedLibraryInfo.getDeclaringPackage().getLongVersionCode(), + is(pkg.getLongVersionCode())); + assertThat(scanResult.mSdkSharedLibraryInfo.getAllCodePaths(), + hasItems("/some/path.apk", "/some/other/path.apk")); + assertThat(scanResult.mSdkSharedLibraryInfo.getDependencies(), nullValue()); + assertThat(scanResult.mSdkSharedLibraryInfo.getDependentPackages(), empty()); + } + + @Test public void installStaticSharedLibrary() throws Exception { final ParsedPackage pkg = ((ParsedPackage) createBasicPackage("static.lib.pkg") .setStaticSharedLibName("static.lib") @@ -528,10 +560,10 @@ public class ScanTests { "/data/tmp/randompath/base.apk", createCodePath(packageName), mock(TypedArray.class), false) .setVolumeUuid(UUID_ONE.toString()) - .addUsesStaticLibrary("some.static.library") - .addUsesStaticLibraryVersion(234L) - .addUsesStaticLibrary("some.other.static.library") - .addUsesStaticLibraryVersion(456L) + .addUsesStaticLibrary("some.static.library", 234L, new String[]{"testCert1"}) + .addUsesStaticLibrary("some.other.static.library", 456L, new String[]{"testCert2"}) + .addUsesSdkLibrary("some.sdk.library", 123L, new String[]{"testCert3"}) + .addUsesSdkLibrary("some.other.sdk.library", 789L, new String[]{"testCert4"}) .hideAsParsed()) .setNativeLibraryRootDir("/data/tmp/randompath/base.apk:/lib") .setVersionCodeMajor(1) @@ -557,6 +589,9 @@ public class ScanTests { assertThat(pkgSetting.getUsesStaticLibraries(), arrayContaining("some.static.library", "some.other.static.library")); assertThat(pkgSetting.getUsesStaticLibrariesVersions(), is(new long[]{234L, 456L})); + assertThat(pkgSetting.getUsesSdkLibraries(), + arrayContaining("some.sdk.library", "some.other.sdk.library")); + assertThat(pkgSetting.getUsesSdkLibrariesVersionsMajor(), is(new long[]{123L, 789L})); assertThat(pkgSetting.getPkg(), is(scanResult.mRequest.mParsedPackage)); assertThat(pkgSetting.getPath(), is(new File(createCodePath(packageName)))); assertThat(pkgSetting.getVersionCode(), diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp index 40bbb36337bc..9828b97982ed 100644 --- a/tools/aapt2/dump/DumpManifest.cpp +++ b/tools/aapt2/dump/DumpManifest.cpp @@ -1461,6 +1461,64 @@ class UsesStaticLibrary : public ManifestExtractor::Element { } }; +/** Represents <sdk-library> elements. **/ +class SdkLibrary : public ManifestExtractor::Element { + public: + SdkLibrary() = default; + std::string name; + int versionMajor; + + void Extract(xml::Element* element) override { + auto parent_stack = extractor()->parent_stack(); + if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) { + name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); + versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0); + } + } + + void Print(text::Printer* printer) override { + printer->Print( + StringPrintf("sdk-library: name='%s' versionMajor='%d'\n", name.data(), versionMajor)); + } +}; + +/** Represents <uses-sdk-library> elements. **/ +class UsesSdkLibrary : public ManifestExtractor::Element { + public: + UsesSdkLibrary() = default; + std::string name; + int versionMajor; + std::vector<std::string> certDigests; + + void Extract(xml::Element* element) override { + auto parent_stack = extractor()->parent_stack(); + if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) { + name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); + versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0); + AddCertDigest(element); + } + } + + void AddCertDigest(xml::Element* element) { + std::string digest = GetAttributeStringDefault(FindAttribute(element, CERT_DIGEST_ATTR), ""); + // We allow ":" delimiters in the SHA declaration as this is the format + // emitted by the certtool making it easy for developers to copy/paste. + digest.erase(std::remove(digest.begin(), digest.end(), ':'), digest.end()); + if (!digest.empty()) { + certDigests.push_back(digest); + } + } + + void Print(text::Printer* printer) override { + printer->Print( + StringPrintf("uses-sdk-library: name='%s' versionMajor='%d'", name.data(), versionMajor)); + for (size_t i = 0; i < certDigests.size(); i++) { + printer->Print(StringPrintf(" certDigest='%s'", certDigests[i].data())); + } + printer->Print("\n"); + } +}; + /** Represents <uses-native-library> elements. **/ class UsesNativeLibrary : public ManifestExtractor::Element { public: @@ -2367,6 +2425,7 @@ T* ElementCast(ManifestExtractor::Element* element) { {"required-not-feature", std::is_base_of<RequiredNotFeature, T>::value}, {"screen", std::is_base_of<Screen, T>::value}, {"service", std::is_base_of<Service, T>::value}, + {"sdk-library", std::is_base_of<SdkLibrary, T>::value}, {"static-library", std::is_base_of<StaticLibrary, T>::value}, {"supports-gl-texture", std::is_base_of<SupportsGlTexture, T>::value}, {"supports-input", std::is_base_of<SupportsInput, T>::value}, @@ -2379,6 +2438,7 @@ T* ElementCast(ManifestExtractor::Element* element) { {"uses-permission", std::is_base_of<UsesPermission, T>::value}, {"uses-permission-sdk-23", std::is_base_of<UsesPermissionSdk23, T>::value}, {"uses-sdk", std::is_base_of<UsesSdkBadging, T>::value}, + {"uses-sdk-library", std::is_base_of<UsesSdkLibrary, T>::value}, {"uses-static-library", std::is_base_of<UsesStaticLibrary, T>::value}, }; @@ -2421,6 +2481,7 @@ std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Element::Inflate( {"required-not-feature", &CreateType<RequiredNotFeature>}, {"screen", &CreateType<Screen>}, {"service", &CreateType<Service>}, + {"sdk-library", &CreateType<SdkLibrary>}, {"static-library", &CreateType<StaticLibrary>}, {"supports-gl-texture", &CreateType<SupportsGlTexture>}, {"supports-input", &CreateType<SupportsInput>}, @@ -2433,6 +2494,7 @@ std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Element::Inflate( {"uses-permission", &CreateType<UsesPermission>}, {"uses-permission-sdk-23", &CreateType<UsesPermissionSdk23>}, {"uses-sdk", &CreateType<UsesSdkBadging>}, + {"uses-sdk-library", &CreateType<UsesSdkLibrary>}, {"uses-static-library", &CreateType<UsesStaticLibrary>}, }; diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp index 63b2fcd66247..b46a125b1a0e 100644 --- a/tools/aapt2/link/ManifestFixer.cpp +++ b/tools/aapt2/link/ManifestFixer.cpp @@ -508,6 +508,16 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, uses_static_library_action.Action(RequiredAndroidAttribute("certDigest")); uses_static_library_action["additional-certificate"]; + xml::XmlNodeAction& sdk_library_action = application_action["sdk-library"]; + sdk_library_action.Action(RequiredNameIsJavaPackage); + sdk_library_action.Action(RequiredAndroidAttribute("versionMajor")); + + xml::XmlNodeAction& uses_sdk_library_action = application_action["uses-sdk-library"]; + uses_sdk_library_action.Action(RequiredNameIsJavaPackage); + uses_sdk_library_action.Action(RequiredAndroidAttribute("versionMajor")); + uses_sdk_library_action.Action(RequiredAndroidAttribute("certDigest")); + uses_sdk_library_action["additional-certificate"]; + xml::XmlNodeAction& uses_package_action = application_action["uses-package"]; uses_package_action.Action(RequiredNameIsJavaPackage); uses_package_action["additional-certificate"]; |