Revert "Revert "SDK libraries.""
This reverts commit a22b7e05d4ee2dddb6e89726102b10f0d8257381.
Reason for revert: This is a roll forwards with the fix applied.
Fixes: 208710019
Change-Id: Id4e9029ebe5864ddcc5583ce525e8e70da79f82c
diff --git a/core/api/current.txt b/core/api/current.txt
index f5f3bb09..7949c80 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -13237,6 +13237,7 @@
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 c777bf5..a7f3801 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -697,7 +697,7 @@
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 @@
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 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 7abb694..4ba2ee6 100644
--- a/core/java/android/content/pm/SharedLibraryInfo.java
+++ b/core/java/android/content/pm/SharedLibraryInfo.java
@@ -70,6 +70,13 @@
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 @@
}
/**
+ * @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 @@
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 056f99f..63332e7 100644
--- a/core/java/android/content/pm/parsing/ParsingPackage.java
+++ b/core/java/android/content/pm/parsing/ParsingPackage.java
@@ -103,11 +103,11 @@
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 @@
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 d5957a2..19a8ce9 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
@@ -179,6 +179,10 @@
@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 @@
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 @@
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 @@
}
@Override
- public ParsingPackageImpl addUsesStaticLibrary(String libraryName) {
+ 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 addUsesStaticLibrary(String libraryName, long version,
+ String[] certSha256Digests) {
this.usesStaticLibraries = CollectionUtils.add(this.usesStaticLibraries,
TextUtils.safeIntern(libraryName));
- return this;
- }
-
- @Override
- public ParsingPackageImpl addUsesStaticLibraryVersion(long version) {
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 @@
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 @@
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 @@
}
}
+ 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 @@
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 @@
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 @@
@Nullable
@Override
+ public String getSdkLibName() {
+ return sdkLibName;
+ }
+
+ @Override
+ public int getSdkLibVersionMajor() {
+ return sdkLibVersionMajor;
+ }
+
+ @Nullable
+ @Override
public String getStaticSharedLibName() {
return staticSharedLibName;
}
@@ -1536,6 +1592,18 @@
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 @@
}
@Override
+ public boolean isSdkLibrary() {
+ return getBoolean(Booleans.SDK_LIBRARY);
+ }
+
+ @Override
public boolean isOverlay() {
return getBoolean(Booleans.OVERLAY);
}
@@ -2558,6 +2631,23 @@
}
@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 2933f95..49b3b08 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageRead.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java
@@ -196,6 +196,17 @@
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 @@
@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 d2ac8739..3e537c8 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -117,6 +117,7 @@
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 @@
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 @@
}
}
- 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 @@
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 @@
}
@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 @@
}
@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 @@
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 fcad10c..625b9d1 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.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 @@
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 94717b1..fe58114 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 2d61773..9b21790 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 @@
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 @@
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 @@
flags = updateFlagsForPackage(flags, userId);
- final boolean canSeeStaticLibraries =
+ final boolean canSeeStaticAndSdkLibraries =
mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
== PERMISSION_GRANTED
|| mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
@@ -3744,7 +3808,7 @@
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 @@
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 @@
}
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 @@
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 @@
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 43d60cc..641f24f 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 @@
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 @@
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 5ca0618..d2087ee 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 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 @@
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 @@
}
}
- 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 4767d3a..26a5bbb 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 @@
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 f299e1e..28204ea 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 @@
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 9f5adcb..fe5bce13 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 @@
// - 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 @@
&& !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 @@
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 @@
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 @@
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 fb70470..0564e85 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.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 @@
return runListPermissions();
case "staged-sessions":
return runListStagedSessions();
+ case "sdks":
+ return runListSdks();
case "users":
ServiceManager.getService("user").shellCommand(
getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(),
@@ -792,6 +795,15 @@
}
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 @@
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 @@
}
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);
- }
- pw.println();
+ } 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());
+ }
+ }
+ 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 @@
} 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 dc514c1..923a133 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.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.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 @@
private Set<String> mOldCodePaths;
@Nullable
+ private String[] usesSdkLibraries;
+
+ @Nullable
+ private long[] usesSdkLibrariesVersionsMajor;
+
+ @Nullable
private String[] usesStaticLibraries;
@Nullable
@@ -208,12 +213,16 @@
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 @@
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 @@
@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 @@
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 48b893b..749495c 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 @@
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 9b08ef9..eafe0d98 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 @@
}
}
+ 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 @@
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 @@
PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting),
PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting),
UserManagerService.getInstance(),
+ usesSdkLibraries, parsedPackage.getUsesSdkLibrariesVersionsMajor(),
usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(),
parsedPackage.getMimeGroups(), newDomainSetId);
}
@@ -552,6 +560,10 @@
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 @@
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 eb44a82..f77be1f 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 @@
/** 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 @@
@Nullable PackageSetting pkgSetting,
@Nullable List<String> changedAbiCodePath, boolean existingSettingCopied,
int previousAppId,
+ SharedLibraryInfo sdkSharedLibraryInfo,
SharedLibraryInfo staticSharedLibraryInfo,
List<SharedLibraryInfo> dynamicSharedLibraryInfos) {
mRequest = request;
@@ -68,6 +71,7 @@
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 6a163b2..45994f6 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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
// 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 @@
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 @@
@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 @@
.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 @@
}
}
+ 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 @@
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 @@
}
serializer.attributeFloat(null, "loadingProgress", pkg.getLoadingProgress());
+ writeUsesSdkLibLPw(serializer, pkg.getUsesSdkLibraries(),
+ pkg.getUsesSdkLibrariesVersionsMajor());
+
writeUsesStaticLibLPw(serializer, pkg.getUsesStaticLibraries(),
pkg.getUsesStaticLibrariesVersions());
@@ -2785,6 +2838,9 @@
serializer.attribute(null, "domainSetId", pkg.getDomainSetId().toString());
+ writeUsesSdkLibLPw(serializer, pkg.getUsesSdkLibraries(),
+ pkg.getUsesSdkLibrariesVersionsMajor());
+
writeUsesStaticLibLPw(serializer, pkg.getUsesStaticLibraries(),
pkg.getUsesStaticLibrariesVersions());
@@ -3455,8 +3511,8 @@
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 @@
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 @@
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 @@
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 @@
}
} 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 @@
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 @@
}
}
+ 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 461fca1..dd8fad0 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 32b1e5d..8b2c3a12 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 @@
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 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 82edce6..34575e0 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.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 @@
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 46d32b9..f5e498d 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 @@
@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 @@
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 @@
return getBoolean(Booleans.VENDOR);
}
+ @Override
+ public long getVersionCode() {
+ return mLongVersionCode;
+ }
+
/**
* @hide
*/
@@ -500,10 +511,10 @@
}
@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 @@
}
@DataClass.Generated.Member
- public long getVersionCode() {
+ public long getLongVersionCode() {
return mLongVersionCode;
}
@@ -609,6 +620,16 @@
}
@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 @@
}
@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 9d86081..4b12fd4 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 @@
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 dc93e53..4a35fdf 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 @@
"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 @@
AndroidPackage::getSecondaryNativeLibraryDir,
AndroidPackage::getSharedUserId,
AndroidPackage::getSharedUserLabel,
+ AndroidPackage::getSdkLibName,
+ AndroidPackage::getSdkLibVersionMajor,
AndroidPackage::getStaticSharedLibName,
AndroidPackage::getStaticSharedLibVersion,
AndroidPackage::getTargetSandboxVersion,
@@ -210,6 +222,7 @@
AndroidPackage::isResizeableActivityViaSdkVersion,
AndroidPackage::isRestoreAnyVersion,
AndroidPackage::isSignedWithPlatformKey,
+ AndroidPackage::isSdkLibrary,
AndroidPackage::isStaticSharedLibrary,
AndroidPackage::isStub,
AndroidPackage::isSupportsRtl,
@@ -228,7 +241,7 @@
AndroidPackage::getMinAspectRatio,
AndroidPackage::hasPreserveLegacyExternalStorage,
AndroidPackage::hasRequestForegroundServiceExemption,
- AndroidPackage::hasRequestRawExternalStorageAccess,
+ AndroidPackage::hasRequestRawExternalStorageAccess
)
override fun extraParams() = listOf(
@@ -254,13 +267,6 @@
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 @@
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 @@
{ it.first },
{ it.second.intentFilter.schemesIterator().asSequence().singleOrNull() },
{ it.second.intentFilter.authoritiesIterator().asSequence()
- .singleOrNull()?.host },
+ .singleOrNull()?.host }
)
}
),
@@ -324,7 +330,7 @@
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 @@
}
),
getSetByValue(
- AndroidPackage::getUsesStaticLibrariesCertDigests,
- PackageImpl::addUsesStaticLibraryCertDigests,
- arrayOf("testCertDigest"),
- transformGet = { it?.singleOrNull() },
- compare = Array<String?>?::contentEquals
- ),
- getSetByValue(
AndroidPackage::getActivities,
PackageImpl::addActivity,
"TestActivityName",
@@ -440,7 +439,7 @@
first, second,
{ it.size() },
{ it.keyAt(0) },
- { it.valueAt(0) },
+ { it.valueAt(0) }
)
}
),
@@ -451,7 +450,7 @@
compare = { first, second ->
equalBy(
first, second,
- { it["testProcess"]?.name },
+ { it["testProcess"]?.name }
)
}
),
@@ -471,10 +470,10 @@
PackageManager.Property::getName,
PackageManager.Property::getClassName,
PackageManager.Property::getPackageName,
- PackageManager.Property::getString,
+ PackageManager.Property::getString
)
}
- ),
+ )
)
override fun initialObject() = PackageImpl.forParsing(
@@ -518,6 +517,9 @@
.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 @@
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 0e5640a..ae5984a41 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 @@
}
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 a9a3469..6c9f8fe 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 @@
}
@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 @@
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 @@
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 @@
0 /*pkgFlags*/,
0 /*pkgPrivateFlags*/,
0,
+ null /*usesSdkLibraries*/,
+ null /*usesSdkLibrariesVersions*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -637,6 +708,8 @@
0 /*pkgFlags*/,
0 /*pkgPrivateFlags*/,
UserManagerService.getInstance(),
+ null /*usesSdkLibraries*/,
+ null /*usesSdkLibrariesVersions*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -671,6 +744,8 @@
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 @@
0 /*pkgFlags*/,
0 /*pkgPrivateFlags*/,
UserManagerService.getInstance(),
+ null /*usesSdkLibraries*/,
+ null /*usesSdkLibrariesVersions*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -741,6 +818,8 @@
false /*instantApp*/,
false /*virtualPreload*/,
UserManagerService.getInstance(),
+ null /*usesSdkLibraries*/,
+ null /*usesSdkLibrariesVersions*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -780,6 +859,8 @@
false /*instantApp*/,
false /*virtualPreload*/,
UserManagerService.getInstance(),
+ null /*usesSdkLibraries*/,
+ null /*usesSdkLibrariesVersions*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -822,6 +903,8 @@
false /*instantApp*/,
false /*virtualPreload*/,
UserManagerService.getInstance(),
+ null /*usesSdkLibraries*/,
+ null /*usesSdkLibrariesVersions*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -864,6 +947,8 @@
false /*instantApp*/,
false /*virtualPreload*/,
UserManagerService.getInstance(),
+ null /*usesSdkLibraries*/,
+ null /*usesSdkLibrariesVersions*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -971,6 +1056,25 @@
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 @@
pkgFlags,
0 /*privateFlags*/,
sharedUserId,
+ null /*usesSdkLibraries*/,
+ null /*usesSdkLibrariesVersions*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -1109,6 +1215,8 @@
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 fb092d2..11bac45 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 @@
.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 2146070..94d8358 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 @@
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 @@
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 @@
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 cfdbb5b7..71d5b77 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 @@
}
@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 @@
"/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 @@
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 40bbb36..9828b97 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -1461,6 +1461,64 @@
}
};
+/** 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 @@
{"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 @@
{"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 @@
{"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 @@
{"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 63b2fcd..b46a125 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -508,6 +508,16 @@
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"];