summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt1
-rw-r--r--core/java/android/content/pm/SharedLibraryInfo.java6
-rw-r--r--core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java2
-rw-r--r--core/java/com/android/server/pm/pkg/AndroidPackage.java9
-rw-r--r--core/res/res/values/attrs_manifest.xml4
-rw-r--r--core/res/res/values/public-staging.xml2
-rw-r--r--services/core/java/com/android/server/pm/Computer.java16
-rw-r--r--services/core/java/com/android/server/pm/ComputerEngine.java26
-rw-r--r--services/core/java/com/android/server/pm/DeletePackageHelper.java36
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageSetting.java19
-rw-r--r--services/core/java/com/android/server/pm/ScanPackageUtils.java4
-rw-r--r--services/core/java/com/android/server/pm/Settings.java40
-rw-r--r--services/core/java/com/android/server/pm/SharedLibrariesImpl.java32
-rw-r--r--services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java29
-rw-r--r--services/core/java/com/android/server/pm/pkg/PackageState.java8
-rw-r--r--services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java5
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java27
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java2
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java5
-rw-r--r--services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt4
21 files changed, 229 insertions, 54 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 61c7ec6411c6..c598ac12dd41 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -1216,6 +1216,7 @@ package android {
field public static final int opticalInsetLeft = 16844168; // 0x1010588
field public static final int opticalInsetRight = 16844170; // 0x101058a
field public static final int opticalInsetTop = 16844169; // 0x1010589
+ field @FlaggedApi("android.content.pm.sdk_lib_independence") public static final int optional;
field public static final int order = 16843242; // 0x10101ea
field public static final int orderInCategory = 16843231; // 0x10101df
field public static final int ordering = 16843490; // 0x10102e2
diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java
index fdd2aa1fe5fa..25ba72551b04 100644
--- a/core/java/android/content/pm/SharedLibraryInfo.java
+++ b/core/java/android/content/pm/SharedLibraryInfo.java
@@ -142,8 +142,10 @@ public final class SharedLibraryInfo implements Parcelable {
mName = parcel.readString8();
mVersion = parcel.readLong();
mType = parcel.readInt();
- mDeclaringPackage = parcel.readParcelable(null, android.content.pm.VersionedPackage.class);
- mDependentPackages = parcel.readArrayList(null, android.content.pm.VersionedPackage.class);
+ mDeclaringPackage =
+ parcel.readParcelable(null, android.content.pm.VersionedPackage.class);
+ mDependentPackages =
+ parcel.readArrayList(null, android.content.pm.VersionedPackage.class);
mDependencies = parcel.createTypedArrayList(SharedLibraryInfo.CREATOR);
mIsNative = parcel.readBoolean();
}
diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java
index 4ed361f24439..6c09b7c04fa7 100644
--- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java
+++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackage.java
@@ -112,7 +112,7 @@ public interface ParsingPackage {
ParsingPackage addUsesOptionalNativeLibrary(String libraryName);
ParsingPackage addUsesSdkLibrary(String libraryName, long versionMajor,
- String[] certSha256Digests);
+ String[] certSha256Digests, boolean usesSdkLibrariesOptional);
ParsingPackage addUsesStaticLibrary(String libraryName, long version,
String[] certSha256Digests);
diff --git a/core/java/com/android/server/pm/pkg/AndroidPackage.java b/core/java/com/android/server/pm/pkg/AndroidPackage.java
index 4e4f26cd6ad6..f86595f1ea7b 100644
--- a/core/java/com/android/server/pm/pkg/AndroidPackage.java
+++ b/core/java/com/android/server/pm/pkg/AndroidPackage.java
@@ -1340,6 +1340,15 @@ public interface AndroidPackage {
@Nullable
long[] getUsesSdkLibrariesVersionsMajor();
+
+ /**
+ * @see R.styleable#AndroidManifestUsesSdkLibrary_optional
+ * @hide
+ */
+ @Immutable.Ignore
+ @Nullable
+ boolean[] getUsesSdkLibrariesOptional();
+
/**
* TODO(b/135203078): Move static library stuff to an inner data class
*
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index f8546b73a37e..596cfe5a695d 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2515,6 +2515,10 @@
<attr name="versionMajor" format="integer" />
<!-- The SHA-256 digest of the SDK library signing certificate. -->
<attr name="certDigest" format="string" />
+ <!-- Specify whether the SDK is optional. The default is false, false means app can be
+ installed even if the SDK library doesn't exist, and the SDK library can be uninstalled
+ when the app is still installed. -->
+ <attr name="optional" format="boolean" />
</declare-styleable>
<!-- The <code>static-library</code> tag declares that this apk is providing itself
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index b12f30242e80..f10e7f8c337e 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -115,6 +115,8 @@
<!-- @FlaggedApi("android.companion.virtual.flags.vdm_custom_ime")
@hide @SystemApi -->
<public name="isVirtualDeviceOnly"/>
+ <!-- @FlaggedApi("android.content.pm.sdk_lib_independence") -->
+ <public name="optional"/>
</staging-public-group>
<staging-public-group type="id" first-id="0x01bc0000">
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index 92d469ccbfac..c36c8caf8b19 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -405,9 +405,19 @@ public interface Computer extends PackageDataSnapshot {
boolean isInstallDisabledForPackage(@NonNull String packageName, int uid,
@UserIdInt int userId);
- @Nullable
- List<VersionedPackage> getPackagesUsingSharedLibrary(@NonNull SharedLibraryInfo libInfo,
- @PackageManager.PackageInfoFlagsBits long flags, int callingUid, @UserIdInt int userId);
+ /**
+ * Returns a Pair that contains a list of packages that depend on the target library and the
+ * package library dependency information. The List&lt;VersionedPackage&gt; indicates a list of
+ * packages that depend on the target library, it may be null if no package depends on
+ * the target library. The List&lt;Boolean&gt; indicates whether each VersionedPackage in
+ * the List&lt;VersionedPackage&gt; optionally depends on the target library, where true means
+ * optional and false means required. It may be null if no package depends on
+ * the target library or without dependency information, e.g. uses-static-library.
+ */
+ @NonNull
+ Pair<List<VersionedPackage>, List<Boolean>> getPackagesUsingSharedLibrary(
+ @NonNull SharedLibraryInfo libInfo, @PackageManager.PackageInfoFlagsBits long flags,
+ int callingUid, @UserIdInt int userId);
@Nullable
ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 139c7c0849b0..df7ceda3b2f9 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -3862,11 +3862,13 @@ public class ComputerEngine implements Computer {
Binder.restoreCallingIdentity(identity);
}
+ var usingSharedLibraryPair =
+ getPackagesUsingSharedLibrary(libInfo, flags, callingUid, userId);
SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getPath(),
libInfo.getPackageName(), libInfo.getAllCodePaths(),
libInfo.getName(), libInfo.getLongVersion(),
libInfo.getType(), declaringPackage,
- getPackagesUsingSharedLibrary(libInfo, flags, callingUid, userId),
+ usingSharedLibraryPair.first,
(libInfo.getDependencies() == null
? null
: new ArrayList<>(libInfo.getDependencies())),
@@ -3935,13 +3937,15 @@ public class ComputerEngine implements Computer {
return false;
}
+
@Override
- public List<VersionedPackage> getPackagesUsingSharedLibrary(@NonNull SharedLibraryInfo libInfo,
- @PackageManager.PackageInfoFlagsBits long flags, int callingUid,
- @UserIdInt int userId) {
+ public Pair<List<VersionedPackage>, List<Boolean>> getPackagesUsingSharedLibrary(
+ @NonNull SharedLibraryInfo libInfo, @PackageManager.PackageInfoFlagsBits long flags,
+ int callingUid, @UserIdInt int userId) {
List<VersionedPackage> versionedPackages = null;
final ArrayMap<String, ? extends PackageStateInternal> packageStates = getPackageStates();
final int packageCount = packageStates.size();
+ List<Boolean> usesLibsOptional = null;
for (int i = 0; i < packageCount; i++) {
PackageStateInternal ps = packageStates.valueAt(i);
if (ps == null) {
@@ -3958,12 +3962,15 @@ public class ComputerEngine implements Computer {
libInfo.isStatic() ? ps.getUsesStaticLibraries() : ps.getUsesSdkLibraries();
final long[] libsVersions = libInfo.isStatic() ? ps.getUsesStaticLibrariesVersions()
: ps.getUsesSdkLibrariesVersionsMajor();
+ final boolean[] libsOptional = libInfo.isSdk()
+ ? ps.getUsesSdkLibrariesOptional() : null;
final int libIdx = ArrayUtils.indexOf(libs, libName);
if (libIdx < 0) {
continue;
}
if (libsVersions[libIdx] != libInfo.getLongVersion()) {
+ // Not expected StaticLib/SdkLib version
continue;
}
if (shouldFilterApplication(ps, callingUid, userId)) {
@@ -3972,6 +3979,9 @@ public class ComputerEngine implements Computer {
if (versionedPackages == null) {
versionedPackages = new ArrayList<>();
}
+ if (usesLibsOptional == null) {
+ usesLibsOptional = new ArrayList<>();
+ }
// If the dependent is a static shared lib, use the public package name
String dependentPackageName = ps.getPackageName();
if (ps.getPkg() != null && ps.getPkg().isStaticSharedLibrary()) {
@@ -3979,6 +3989,7 @@ public class ComputerEngine implements Computer {
}
versionedPackages.add(new VersionedPackage(dependentPackageName,
ps.getVersionCode()));
+ usesLibsOptional.add(libsOptional != null && libsOptional[libIdx]);
} else if (ps.getPkg() != null) {
if (ArrayUtils.contains(ps.getPkg().getUsesLibraries(), libName)
|| ArrayUtils.contains(ps.getPkg().getUsesOptionalLibraries(), libName)) {
@@ -3994,7 +4005,7 @@ public class ComputerEngine implements Computer {
}
}
- return versionedPackages;
+ return new Pair<>(versionedPackages, usesLibsOptional);
}
@Nullable
@@ -4053,13 +4064,14 @@ public class ComputerEngine implements Computer {
Binder.restoreCallingIdentity(identity);
}
+ var usingSharedLibraryPair =
+ getPackagesUsingSharedLibrary(libraryInfo, flags, callingUid, userId);
SharedLibraryInfo resultLibraryInfo = new SharedLibraryInfo(
libraryInfo.getPath(), libraryInfo.getPackageName(),
libraryInfo.getAllCodePaths(), libraryInfo.getName(),
libraryInfo.getLongVersion(), libraryInfo.getType(),
libraryInfo.getDeclaringPackage(),
- getPackagesUsingSharedLibrary(
- libraryInfo, flags, callingUid, userId),
+ usingSharedLibraryPair.first,
libraryInfo.getDependencies() == null
? null : new ArrayList<>(libraryInfo.getDependencies()),
libraryInfo.isNative());
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 80e6c833dfb2..93836266d1f4 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -18,7 +18,6 @@ package com.android.server.pm;
import static android.Manifest.permission.CONTROL_KEYGUARD;
import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
-import static android.content.pm.Flags.sdkLibIndependence;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
@@ -40,6 +39,7 @@ import android.app.ApplicationExitInfo;
import android.app.ApplicationPackageManager;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.Flags;
import android.content.pm.IPackageDeleteObserver2;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
@@ -72,8 +72,6 @@ import com.android.server.wm.ActivityTaskManagerInternal;
import dalvik.system.VMRuntime;
-import java.util.List;
-
/**
* Deletes a package. Uninstall if installed, or at least deletes the base directory if it's called
* from a failed installation. Fixes user state after deletion.
@@ -181,16 +179,36 @@ final class DeletePackageHelper {
}
if (libraryInfo != null) {
+ boolean flagSdkLibIndependence = Flags.sdkLibIndependence();
for (int currUserId : allUsers) {
if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
continue;
}
- List<VersionedPackage> libClientPackages =
- computer.getPackagesUsingSharedLibrary(libraryInfo,
- MATCH_KNOWN_PACKAGES, Process.SYSTEM_UID, currUserId);
- boolean allowSdkLibIndependence =
- (pkg.getSdkLibraryName() != null) && sdkLibIndependence();
- if (!ArrayUtils.isEmpty(libClientPackages) && !allowSdkLibIndependence) {
+ var libClientPackagesPair = computer.getPackagesUsingSharedLibrary(
+ libraryInfo, MATCH_KNOWN_PACKAGES, Process.SYSTEM_UID, currUserId);
+ var libClientPackages = libClientPackagesPair.first;
+ var libClientOptional = libClientPackagesPair.second;
+ // We by default don't allow removing a package if the host lib is still be
+ // used by other client packages
+ boolean allowLibIndependence = false;
+ // Only when the sdkLibIndependence flag is enabled we will respect the
+ // "optional" attr in uses-sdk-library. Only allow to remove sdk-lib host
+ // package if no required clients depend on it
+ if ((pkg.getSdkLibraryName() != null)
+ && !ArrayUtils.isEmpty(libClientPackages)
+ && !ArrayUtils.isEmpty(libClientOptional)
+ && (libClientPackages.size() == libClientOptional.size())
+ && flagSdkLibIndependence) {
+ allowLibIndependence = true;
+ for (int i = 0; i < libClientPackages.size(); i++) {
+ boolean usesSdkLibOptional = libClientOptional.get(i);
+ if (!usesSdkLibOptional) {
+ allowLibIndependence = false;
+ break;
+ }
+ }
+ }
+ if (!ArrayUtils.isEmpty(libClientPackages) && !allowLibIndependence) {
Slog.w(TAG, "Not removing package " + pkg.getManifestPackageName()
+ " hosting lib " + libraryInfo.getName() + " version "
+ libraryInfo.getLongVersion() + " used by " + libClientPackages
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f27c462700be..2880f84c6445 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7113,9 +7113,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService
if (info == null) {
continue;
}
- final List<VersionedPackage> dependents =
- computer.getPackagesUsingSharedLibrary(info, 0, Process.SYSTEM_UID,
- userId);
+ var usingSharedLibraryPair = computer.getPackagesUsingSharedLibrary(info, 0,
+ Process.SYSTEM_UID, userId);
+ final List<VersionedPackage> dependents = usingSharedLibraryPair.first;
if (dependents == null) {
continue;
}
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 174df44c4263..7d0a1f6afe1d 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -123,11 +123,15 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
@Nullable
private Map<String, Set<String>> mimeGroups;
+ // TODO(b/314036181): encapsulate all these fields for usesSdk, instead of having three
+ // separate arrays.
@Nullable
private String[] usesSdkLibraries;
@Nullable
private long[] usesSdkLibrariesVersionsMajor;
+ @Nullable
+ private boolean[] usesSdkLibrariesOptional;
@Nullable
private String[] usesStaticLibraries;
@@ -701,6 +705,9 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
usesSdkLibrariesVersionsMajor = other.usesSdkLibrariesVersionsMajor != null
? Arrays.copyOf(other.usesSdkLibrariesVersionsMajor,
other.usesSdkLibrariesVersionsMajor.length) : null;
+ usesSdkLibrariesOptional = other.usesSdkLibrariesOptional != null
+ ? Arrays.copyOf(other.usesSdkLibrariesOptional,
+ other.usesSdkLibrariesOptional.length) : null;
usesStaticLibraries = other.usesStaticLibraries != null
? Arrays.copyOf(other.usesStaticLibraries,
@@ -1344,6 +1351,12 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
@NonNull
@Override
+ public boolean[] getUsesSdkLibrariesOptional() {
+ return usesSdkLibrariesOptional == null ? EmptyArray.BOOLEAN : usesSdkLibrariesOptional;
+ }
+
+ @NonNull
+ @Override
public String[] getUsesStaticLibraries() {
return usesStaticLibraries == null ? EmptyArray.STRING : usesStaticLibraries;
}
@@ -1444,6 +1457,12 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
return this;
}
+ public PackageSetting setUsesSdkLibrariesOptional(boolean[] usesSdkLibrariesOptional) {
+ this.usesSdkLibrariesOptional = usesSdkLibrariesOptional;
+ onChanged();
+ return this;
+ }
+
public PackageSetting setUsesStaticLibraries(String[] usesStaticLibraries) {
this.usesStaticLibraries = usesStaticLibraries;
onChanged();
diff --git a/services/core/java/com/android/server/pm/ScanPackageUtils.java b/services/core/java/com/android/server/pm/ScanPackageUtils.java
index 53b84e66840b..31a63e07b66c 100644
--- a/services/core/java/com/android/server/pm/ScanPackageUtils.java
+++ b/services/core/java/com/android/server/pm/ScanPackageUtils.java
@@ -218,7 +218,8 @@ final class ScanPackageUtils {
parsedPackage.getLongVersionCode(), pkgFlags, pkgPrivateFlags, user,
true /*allowInstall*/, instantApp, virtualPreload, isStoppedSystemApp,
UserManagerService.getInstance(), usesSdkLibraries,
- parsedPackage.getUsesSdkLibrariesVersionsMajor(), usesStaticLibraries,
+ parsedPackage.getUsesSdkLibrariesVersionsMajor(),
+ parsedPackage.getUsesSdkLibrariesOptional(), usesStaticLibraries,
parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups(),
newDomainSetId,
parsedPackage.getTargetSdkVersion(), parsedPackage.getRestrictUpdateHash());
@@ -240,6 +241,7 @@ final class ScanPackageUtils {
PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting),
UserManagerService.getInstance(),
usesSdkLibraries, parsedPackage.getUsesSdkLibrariesVersionsMajor(),
+ parsedPackage.getUsesSdkLibrariesOptional(),
usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(),
parsedPackage.getMimeGroups(), newDomainSetId,
parsedPackage.getTargetSdkVersion(), parsedPackage.getRestrictUpdateHash());
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 2cbf714792f7..75d88da059b5 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -106,6 +106,7 @@ import com.android.server.LocalServices;
import com.android.server.backup.PreferredActivityBackupHelper;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.parsing.PackageInfoUtils;
+import com.android.server.pm.parsing.pkg.PackageImpl;
import com.android.server.pm.permission.LegacyPermissionDataProvider;
import com.android.server.pm.permission.LegacyPermissionSettings;
import com.android.server.pm.permission.LegacyPermissionState;
@@ -339,6 +340,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
private static final String ATTR_DISTRACTION_FLAGS = "distraction_flags";
private static final String ATTR_SUSPENDED = "suspended";
private static final String ATTR_SUSPENDING_PACKAGE = "suspending-package";
+
+ private static final String ATTR_OPTIONAL = "optional";
/**
* @deprecated Legacy attribute, kept only for upgrading from P builds.
*/
@@ -942,6 +945,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
ret.setLongVersionCode(p.getVersionCode());
ret.setUsesSdkLibraries(p.getUsesSdkLibraries());
ret.setUsesSdkLibrariesVersionsMajor(p.getUsesSdkLibrariesVersionsMajor());
+ ret.setUsesSdkLibrariesOptional(p.getUsesSdkLibrariesOptional());
ret.setUsesStaticLibraries(p.getUsesStaticLibraries());
ret.setUsesStaticLibrariesVersions(p.getUsesStaticLibrariesVersions());
ret.setMimeGroups(p.getMimeGroups());
@@ -1061,9 +1065,9 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
UserHandle installUser, boolean allowInstall, boolean instantApp,
boolean virtualPreload, boolean isStoppedSystemApp, UserManagerService userManager,
String[] usesSdkLibraries, long[] usesSdkLibrariesVersions,
- String[] usesStaticLibraries, long[] usesStaticLibrariesVersions,
- Set<String> mimeGroupNames, @NonNull UUID domainSetId,
- int targetSdkVersion, byte[] restrictUpdatedHash) {
+ boolean[] usesSdkLibrariesOptional, String[] usesStaticLibraries,
+ long[] usesStaticLibrariesVersions, Set<String> mimeGroupNames,
+ @NonNull UUID domainSetId, int targetSdkVersion, byte[] restrictUpdatedHash) {
final PackageSetting pkgSetting;
if (originalPkg != null) {
if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
@@ -1079,6 +1083,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
.setLongVersionCode(versionCode)
.setUsesSdkLibraries(usesSdkLibraries)
.setUsesSdkLibrariesVersionsMajor(usesSdkLibrariesVersions)
+ .setUsesSdkLibrariesOptional(usesSdkLibrariesOptional)
.setUsesStaticLibraries(usesStaticLibraries)
.setUsesStaticLibrariesVersions(usesStaticLibrariesVersions)
// Update new package state.
@@ -1096,6 +1101,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
pkgPrivateFlags, domainSetId)
.setUsesSdkLibraries(usesSdkLibraries)
.setUsesSdkLibrariesVersionsMajor(usesSdkLibrariesVersions)
+ .setUsesSdkLibrariesOptional(usesSdkLibrariesOptional)
.setUsesStaticLibraries(usesStaticLibraries)
.setUsesStaticLibrariesVersions(usesStaticLibrariesVersions)
.setLegacyNativeLibraryPath(legacyNativeLibraryPath)
@@ -1218,6 +1224,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
@Nullable String primaryCpuAbi, @Nullable String secondaryCpuAbi, int pkgFlags,
int pkgPrivateFlags, @NonNull UserManagerService userManager,
@Nullable String[] usesSdkLibraries, @Nullable long[] usesSdkLibrariesVersions,
+ @Nullable boolean[] usesSdkLibrariesOptional,
@Nullable String[] usesStaticLibraries, @Nullable long[] usesStaticLibrariesVersions,
@Nullable Set<String> mimeGroupNames, @NonNull UUID domainSetId,
int targetSdkVersion, byte[] restrictUpdatedHash)
@@ -1277,12 +1284,17 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
.setRestrictUpdateHash(restrictUpdatedHash);
// Update SDK library dependencies if needed.
if (usesSdkLibraries != null && usesSdkLibrariesVersions != null
- && usesSdkLibraries.length == usesSdkLibrariesVersions.length) {
+ && usesSdkLibrariesOptional != null
+ && usesSdkLibraries.length == usesSdkLibrariesVersions.length
+ && usesSdkLibraries.length == usesSdkLibrariesOptional.length) {
pkgSetting.setUsesSdkLibraries(usesSdkLibraries)
- .setUsesSdkLibrariesVersionsMajor(usesSdkLibrariesVersions);
+ .setUsesSdkLibrariesVersionsMajor(usesSdkLibrariesVersions)
+ .setUsesSdkLibrariesOptional(usesSdkLibrariesOptional);
} else {
pkgSetting.setUsesSdkLibraries(null)
- .setUsesSdkLibrariesVersionsMajor(null);
+ .setUsesSdkLibrariesVersionsMajor(null)
+ .setUsesSdkLibrariesOptional(null);
+
}
// Update static shared library dependencies if needed.
@@ -2537,12 +2549,15 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
throws IOException, XmlPullParserException {
String libName = parser.getAttributeValue(null, ATTR_NAME);
long libVersion = parser.getAttributeLong(null, ATTR_VERSION, -1);
+ boolean optional = parser.getAttributeBoolean(null, ATTR_OPTIONAL, true);
if (libName != null && libVersion >= 0) {
outPs.setUsesSdkLibraries(ArrayUtils.appendElement(String.class,
outPs.getUsesSdkLibraries(), libName));
outPs.setUsesSdkLibrariesVersionsMajor(ArrayUtils.appendLong(
outPs.getUsesSdkLibrariesVersionsMajor(), libVersion));
+ outPs.setUsesSdkLibrariesOptional(PackageImpl.appendBoolean(
+ outPs.getUsesSdkLibrariesOptional(), optional));
}
XmlUtils.skipCurrentTag(parser);
@@ -2564,7 +2579,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
}
void writeUsesSdkLibLPw(TypedXmlSerializer serializer, String[] usesSdkLibraries,
- long[] usesSdkLibraryVersions) throws IOException {
+ long[] usesSdkLibraryVersions, boolean[] usesSdkLibrariesOptional) throws IOException {
if (ArrayUtils.isEmpty(usesSdkLibraries) || ArrayUtils.isEmpty(usesSdkLibraryVersions)
|| usesSdkLibraries.length != usesSdkLibraryVersions.length) {
return;
@@ -2573,9 +2588,11 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
for (int i = 0; i < libCount; i++) {
final String libName = usesSdkLibraries[i];
final long libVersion = usesSdkLibraryVersions[i];
+ boolean libOptional = usesSdkLibrariesOptional[i];
serializer.startTag(null, TAG_USES_SDK_LIB);
serializer.attribute(null, ATTR_NAME, libName);
serializer.attributeLong(null, ATTR_VERSION, libVersion);
+ serializer.attributeBoolean(null, ATTR_OPTIONAL, libOptional);
serializer.endTag(null, TAG_USES_SDK_LIB);
}
}
@@ -3106,7 +3123,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
}
writeUsesSdkLibLPw(serializer, pkg.getUsesSdkLibraries(),
- pkg.getUsesSdkLibrariesVersionsMajor());
+ pkg.getUsesSdkLibrariesVersionsMajor(), pkg.getUsesSdkLibrariesOptional());
+
writeUsesStaticLibLPw(serializer, pkg.getUsesStaticLibraries(),
pkg.getUsesStaticLibrariesVersions());
@@ -3206,7 +3224,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
}
writeUsesSdkLibLPw(serializer, pkg.getUsesSdkLibraries(),
- pkg.getUsesSdkLibrariesVersionsMajor());
+ pkg.getUsesSdkLibrariesVersionsMajor(), pkg.getUsesSdkLibrariesOptional());
writeUsesStaticLibLPw(serializer, pkg.getUsesStaticLibraries(),
pkg.getUsesStaticLibrariesVersions());
@@ -5091,12 +5109,14 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
List<String> usesSdkLibraries = pkg.getUsesSdkLibraries();
long[] usesSdkLibrariesVersionsMajor = pkg.getUsesSdkLibrariesVersionsMajor();
+ boolean[] usesSdkLibrariesOptional = pkg.getUsesSdkLibrariesOptional();
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]);
+ pw.println(usesSdkLibrariesVersionsMajor[i]); pw.print(" optional:");
+ pw.println(usesSdkLibrariesOptional[i]);
}
}
diff --git a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
index 9384c13e583b..94495bf462f2 100644
--- a/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
+++ b/services/core/java/com/android/server/pm/SharedLibrariesImpl.java
@@ -16,7 +16,6 @@
package com.android.server.pm;
-import static android.content.pm.Flags.sdkLibIndependence;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_LIBRARY_BAD_CERTIFICATE_DIGEST;
@@ -28,6 +27,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
+import android.content.pm.Flags;
import android.content.pm.PackageManager;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.Signature;
@@ -82,6 +82,8 @@ import java.util.function.BiConsumer;
public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable, Snappable {
private static final boolean DEBUG_SHARED_LIBRARIES = false;
+ private static final String LIBRARY_TYPE_SDK = "sdk";
+
/**
* Apps targeting Android S and above need to declare dependencies to the public native
* shared libraries that are defined by the device maker using {@code uses-native-library} tag
@@ -798,8 +800,9 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
// Remove the shared library overlays from its dependent packages.
for (int currentUserId : mPm.mUserManager.getUserIds()) {
- final List<VersionedPackage> dependents = snapshot.getPackagesUsingSharedLibrary(
- libraryInfo, 0, Process.SYSTEM_UID, currentUserId);
+ var usingSharedLibraryPair = snapshot.getPackagesUsingSharedLibrary(libraryInfo, 0,
+ Process.SYSTEM_UID, currentUserId);
+ final List<VersionedPackage> dependents = usingSharedLibraryPair.first;
if (dependents == null) {
continue;
}
@@ -921,42 +924,43 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
// duplicates.
ArrayList<SharedLibraryInfo> usesLibraryInfos = null;
if (!pkg.getUsesLibraries().isEmpty()) {
- usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesLibraries(), null, null,
+ usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesLibraries(), null, null, null,
pkg.getPackageName(), "shared", true, pkg.getTargetSdkVersion(), null,
availablePackages, newLibraries);
}
if (!pkg.getUsesStaticLibraries().isEmpty()) {
usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesStaticLibraries(),
pkg.getUsesStaticLibrariesVersions(), pkg.getUsesStaticLibrariesCertDigests(),
- pkg.getPackageName(), "static shared", true, pkg.getTargetSdkVersion(),
- usesLibraryInfos, availablePackages, newLibraries);
+ null, pkg.getPackageName(), "static shared", true,
+ pkg.getTargetSdkVersion(), usesLibraryInfos, availablePackages, newLibraries);
}
if (!pkg.getUsesOptionalLibraries().isEmpty()) {
usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalLibraries(), null, null,
- pkg.getPackageName(), "shared", false, pkg.getTargetSdkVersion(),
+ null, pkg.getPackageName(), "shared", false, pkg.getTargetSdkVersion(),
usesLibraryInfos, availablePackages, 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(), "native shared", true,
+ null, null, pkg.getPackageName(), "native shared", true,
pkg.getTargetSdkVersion(), usesLibraryInfos, availablePackages,
newLibraries);
}
if (!pkg.getUsesOptionalNativeLibraries().isEmpty()) {
usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalNativeLibraries(),
- null, null, pkg.getPackageName(), "native shared", false,
+ null, null, null, pkg.getPackageName(), "native shared", false,
pkg.getTargetSdkVersion(), usesLibraryInfos, availablePackages,
newLibraries);
}
}
if (!pkg.getUsesSdkLibraries().isEmpty()) {
// Allow installation even if sdk-library dependency doesn't exist
- boolean required = !sdkLibIndependence();
+ boolean required = !Flags.sdkLibIndependence();
usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesSdkLibraries(),
pkg.getUsesSdkLibrariesVersionsMajor(), pkg.getUsesSdkLibrariesCertDigests(),
- pkg.getPackageName(), "sdk", required, pkg.getTargetSdkVersion(),
+ pkg.getUsesSdkLibrariesOptional(),
+ pkg.getPackageName(), LIBRARY_TYPE_SDK, required, pkg.getTargetSdkVersion(),
usesLibraryInfos, availablePackages, newLibraries);
}
return usesLibraryInfos;
@@ -965,6 +969,7 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
private ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(
@NonNull List<String> requestedLibraries,
@Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
+ @Nullable boolean[] libsOptional,
@NonNull String packageName, @NonNull String libraryType, boolean required,
int targetSdk, @Nullable ArrayList<SharedLibraryInfo> outUsedLibraries,
@NonNull final Map<String, AndroidPackage> availablePackages,
@@ -981,7 +986,10 @@ public final class SharedLibrariesImpl implements SharedLibrariesRead, Watchable
libName, libVersion, mSharedLibraries, newLibraries);
}
if (libraryInfo == null) {
- if (required) {
+ // Only allow app be installed if the app specifies the sdk-library dependency is
+ // optional
+ if (required || (LIBRARY_TYPE_SDK.equals(libraryType) && (libsOptional != null
+ && !libsOptional[i]))) {
throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
"Package " + packageName + " requires unavailable " + libraryType
+ " library " + libName + "; failing!");
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
index 85d95eab2958..da58d47edbfe 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
@@ -267,6 +267,8 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal,
@Nullable
private String[][] usesSdkLibrariesCertDigests;
@Nullable
+ private boolean[] usesSdkLibrariesOptional;
+ @Nullable
@DataClass.ParcelWith(ForInternedString.class)
private String sharedUserId;
private int sharedUserLabel;
@@ -718,16 +720,33 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal,
@Override
public PackageImpl addUsesSdkLibrary(String libraryName, long versionMajor,
- String[] certSha256Digests) {
+ String[] certSha256Digests, boolean usesSdkLibrariesOptional) {
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);
+ this.usesSdkLibrariesOptional = appendBoolean(this.usesSdkLibrariesOptional,
+ usesSdkLibrariesOptional);
return this;
}
+ /**
+ * Adds value to given array if not already present, providing set-like
+ * behavior.
+ */
+ public static boolean[] appendBoolean(@Nullable boolean[] cur, boolean val) {
+ if (cur == null) {
+ return new boolean[] { val };
+ }
+ final int N = cur.length;
+ boolean[] ret = new boolean[N + 1];
+ System.arraycopy(cur, 0, ret, 0, N);
+ ret[N] = val;
+ return ret;
+ }
+
@Override
public PackageImpl addUsesStaticLibrary(String libraryName, long version,
String[] certSha256Digests) {
@@ -1468,6 +1487,12 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal,
@Override
public long[] getUsesSdkLibrariesVersionsMajor() { return usesSdkLibrariesVersionsMajor; }
+ @Nullable
+ @Override
+ public boolean[] getUsesSdkLibrariesOptional() {
+ return usesSdkLibrariesOptional;
+ }
+
@NonNull
@Override
public List<String> getUsesStaticLibraries() {
@@ -3126,6 +3151,7 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal,
dest.writeStringArray(this.usesSdkLibrariesCertDigests[index]);
}
}
+ dest.writeBooleanArray(this.usesSdkLibrariesOptional);
sForInternedString.parcel(this.sharedUserId, dest, flags);
dest.writeInt(this.sharedUserLabel);
@@ -3278,6 +3304,7 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal,
}
}
}
+ this.usesSdkLibrariesOptional = in.createBooleanArray();
this.sharedUserId = sForInternedString.unparcel(in);
this.sharedUserLabel = in.readInt();
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 10b59c7230f6..a7ae4ebcb2eb 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageState.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageState.java
@@ -322,6 +322,14 @@ public interface PackageState {
long[] getUsesSdkLibrariesVersionsMajor();
/**
+ * @see R.styleable#AndroidManifestUsesSdkLibrary_optional
+ * @hide
+ */
+ @Immutable.Ignore
+ @NonNull
+ boolean[] getUsesSdkLibrariesOptional();
+
+ /**
* @see R.styleable#AndroidManifestUsesStaticLibrary
* @hide
*/
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index 722350a0d7fb..aa0fb2734382 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -2598,6 +2598,8 @@ public class ParsingPackageUtils {
R.styleable.AndroidManifestUsesSdkLibrary_versionMajor, -1);
String certSha256Digest = sa.getNonResourceString(R.styleable
.AndroidManifestUsesSdkLibrary_certDigest);
+ boolean optional =
+ sa.getBoolean(R.styleable.AndroidManifestUsesSdkLibrary_optional, false);
// Since an APK providing a static shared lib can only provide the lib - fail if
// malformed
@@ -2641,7 +2643,8 @@ public class ParsingPackageUtils {
System.arraycopy(additionalCertSha256Digests, 0, certSha256Digests,
1, additionalCertSha256Digests.length);
- return input.success(pkg.addUsesSdkLibrary(lname, versionMajor, certSha256Digests));
+ return input.success(
+ pkg.addUsesSdkLibrary(lname, versionMajor, certSha256Digests, optional));
} finally {
sa.recycle();
}
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
index a0dc2b68415c..f07e820bf8b3 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -817,12 +817,14 @@ public class PackageManagerSettingsTests {
ps1.setUsesSdkLibraries(new String[] { "com.example.sdk.one" });
ps1.setUsesSdkLibrariesVersionsMajor(new long[] { 12 });
+ ps1.setUsesSdkLibrariesOptional(new boolean[] {true});
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 });
+ ps2.setUsesSdkLibrariesOptional(new boolean[] {false});
settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
settingsUnderTest.writeLPr(computer, /*sync=*/true);
@@ -838,19 +840,30 @@ public class PackageManagerSettingsTests {
Truth.assertThat(readPs1).isNotNull();
Truth.assertThat(readPs1.getUsesSdkLibraries()).isNotNull();
Truth.assertThat(readPs1.getUsesSdkLibrariesVersionsMajor()).isNotNull();
+ Truth.assertThat(readPs1.getUsesSdkLibrariesOptional()).isNotNull();
Truth.assertThat(readPs2).isNotNull();
Truth.assertThat(readPs2.getUsesSdkLibraries()).isNotNull();
Truth.assertThat(readPs2.getUsesSdkLibrariesVersionsMajor()).isNotNull();
+ Truth.assertThat(readPs2.getUsesSdkLibrariesOptional()).isNotNull();
List<Long> ps1VersionsAsList = new ArrayList<>();
for (long version : ps1.getUsesSdkLibrariesVersionsMajor()) {
ps1VersionsAsList.add(version);
}
+ List<Boolean> ps1RequireAsList = new ArrayList<>();
+ for (boolean optional : ps1.getUsesSdkLibrariesOptional()) {
+ ps1RequireAsList.add(optional);
+ }
+
List<Long> ps2VersionsAsList = new ArrayList<>();
for (long version : ps2.getUsesSdkLibrariesVersionsMajor()) {
ps2VersionsAsList.add(version);
}
+ List<Boolean> ps2RequireAsList = new ArrayList<>();
+ for (boolean optional : ps2.getUsesSdkLibrariesOptional()) {
+ ps2RequireAsList.add(optional);
+ }
Truth.assertThat(readPs1.getUsesSdkLibraries()).asList()
.containsExactlyElementsIn(ps1.getUsesSdkLibraries()).inOrder();
@@ -858,11 +871,17 @@ public class PackageManagerSettingsTests {
Truth.assertThat(readPs1.getUsesSdkLibrariesVersionsMajor()).asList()
.containsExactlyElementsIn(ps1VersionsAsList).inOrder();
+ Truth.assertThat(readPs1.getUsesSdkLibrariesOptional()).asList()
+ .containsExactlyElementsIn(ps1RequireAsList).inOrder();
+
Truth.assertThat(readPs2.getUsesSdkLibraries()).asList()
.containsExactlyElementsIn(ps2.getUsesSdkLibraries()).inOrder();
Truth.assertThat(readPs2.getUsesSdkLibrariesVersionsMajor()).asList()
.containsExactlyElementsIn(ps2VersionsAsList).inOrder();
+
+ Truth.assertThat(readPs2.getUsesSdkLibrariesOptional()).asList()
+ .containsExactlyElementsIn(ps2RequireAsList).inOrder();
}
@Test
@@ -1047,6 +1066,7 @@ public class PackageManagerSettingsTests {
UserManagerService.getInstance(),
null /*usesSdkLibraries*/,
null /*usesSdkLibrariesVersions*/,
+ null /*usesSdkLibrariesOptional*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -1087,6 +1107,7 @@ public class PackageManagerSettingsTests {
UserManagerService.getInstance(),
null /*usesSdkLibraries*/,
null /*usesSdkLibrariesVersions*/,
+ null /*usesSdkLibrariesOptional*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -1129,6 +1150,7 @@ public class PackageManagerSettingsTests {
UserManagerService.getInstance(),
null /*usesSdkLibraries*/,
null /*usesSdkLibrariesVersions*/,
+ null /*usesSdkLibrariesOptional*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -1167,6 +1189,7 @@ public class PackageManagerSettingsTests {
UserManagerService.getInstance(),
null /*usesSdkLibraries*/,
null /*usesSdkLibrariesVersions*/,
+ null /*usesSdkLibrariesOptional*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -1214,6 +1237,7 @@ public class PackageManagerSettingsTests {
UserManagerService.getInstance(),
null /*usesSdkLibraries*/,
null /*usesSdkLibrariesVersions*/,
+ null /*usesSdkLibrariesOptional*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
@@ -1263,6 +1287,7 @@ public class PackageManagerSettingsTests {
null /*usesSdkLibrariesVersions*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
+ null /*usesSdkLibrariesOptional*/,
null /*mimeGroups*/,
UUID.randomUUID(),
34 /*targetSdkVersion*/,
@@ -1311,6 +1336,7 @@ public class PackageManagerSettingsTests {
null /*usesSdkLibrariesVersions*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
+ null /*usesSdkLibrariesOptional*/,
null /*mimeGroups*/,
UUID.randomUUID(),
34 /*targetSdkVersion*/,
@@ -1356,6 +1382,7 @@ public class PackageManagerSettingsTests {
null /*usesSdkLibrariesVersions*/,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/,
+ null /*usesSdkLibrariesOptional*/,
null /*mimeGroups*/,
UUID.randomUUID(),
34 /*targetSdkVersion*/,
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java
index ea88ec25b26e..a62cd4fc5fc2 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageParserTest.java
@@ -1062,7 +1062,7 @@ public class PackageParserTest {
.addProtectedBroadcast("foo8")
.setSdkLibraryName("sdk12")
.setSdkLibVersionMajor(42)
- .addUsesSdkLibrary("sdk23", 200, new String[]{"digest2"})
+ .addUsesSdkLibrary("sdk23", 200, new String[]{"digest2"}, true)
.setStaticSharedLibraryName("foo23")
.setStaticSharedLibraryVersion(100)
.addUsesStaticLibrary("foo23", 100, new String[]{"digest"})
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java
index decb44c2cd9b..6202908cdfbf 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java
@@ -599,8 +599,8 @@ public class ScanTests {
.setVolumeUuid(UUID_ONE.toString())
.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"})
+ .addUsesSdkLibrary("some.sdk.library", 123L, new String[]{"testCert3"}, false)
+ .addUsesSdkLibrary("some.other.sdk.library", 789L, new String[]{"testCert4"}, true)
.hideAsParsed())
.setNativeLibraryRootDir("/data/tmp/randompath/base.apk:/lib")
.setVersionCodeMajor(1)
@@ -628,6 +628,7 @@ public class ScanTests {
assertThat(pkgSetting.getUsesSdkLibraries(),
arrayContaining("some.sdk.library", "some.other.sdk.library"));
assertThat(pkgSetting.getUsesSdkLibrariesVersionsMajor(), is(new long[]{123L, 789L}));
+ assertThat(pkgSetting.getUsesSdkLibrariesOptional(), is(new boolean[]{false, true}));
assertThat(pkgSetting.getPkg(), is(scanResult.mRequest.mParsedPackage));
assertThat(pkgSetting.getPath(), is(new File(createCodePath(packageName))));
assertThat(pkgSetting.getVersionCode(),
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 170faf61858b..09b66c11d200 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
@@ -127,6 +127,7 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag
"getUsesSdkLibraries",
"getUsesSdkLibrariesVersionsMajor",
"getUsesSdkLibrariesCertDigests",
+ "getUsesSdkLibrariesOptional",
// Tested through addUsesStaticLibrary
"addUsesStaticLibrary",
"getUsesStaticLibraries",
@@ -608,7 +609,7 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag
.setSplitHasCode(1, false)
.setSplitClassLoaderName(0, "testSplitClassLoaderNameZero")
.setSplitClassLoaderName(1, "testSplitClassLoaderNameOne")
- .addUsesSdkLibrary("testSdk", 2L, arrayOf("testCertDigest1"))
+ .addUsesSdkLibrary("testSdk", 2L, arrayOf("testCertDigest1"), true)
.addUsesStaticLibrary("testStatic", 3L, arrayOf("testCertDigest2"))
override fun finalizeObject(parcelable: Parcelable) {
@@ -661,6 +662,7 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag
expect.that(after.usesSdkLibrariesCertDigests!!.size).isEqualTo(1)
expect.that(after.usesSdkLibrariesCertDigests!![0]).asList()
.containsExactly("testCertDigest1")
+ expect.that(after.usesSdkLibrariesOptional).asList().containsExactly(true)
expect.that(after.usesStaticLibraries).containsExactly("testStatic")
expect.that(after.usesStaticLibrariesVersions).asList().containsExactly(3L)