diff options
8 files changed, 89 insertions, 65 deletions
diff --git a/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt b/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt index 9e519f7afb93..1d94d7e8eca2 100644 --- a/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt +++ b/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt @@ -178,7 +178,7 @@ class PackageParsingPerfTest { // For testing, just disable enforcement to avoid hooking up to compat framework ParseTypeImpl(ParseInput.Callback { _, _, _ -> false }) } - val parser = ParsingPackageUtils(false, null, null, + val parser = ParsingPackageUtils(false, null, null, emptyList(), object : ParsingPackageUtils.Callback { override fun hasFeature(feature: String) = true diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 7e7f887766e2..b51d4ac8c988 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -59,6 +59,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageInstaller; import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageUserState; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; @@ -70,6 +71,12 @@ import android.content.pm.SuspendDialogInfo; import android.content.pm.VerifierDeviceIdentity; import android.content.pm.VersionedPackage; import android.content.pm.dex.ArtManager; +import android.content.pm.parsing.PackageInfoWithoutStateUtils; +import android.content.pm.parsing.ParsingPackage; +import android.content.pm.parsing.ParsingPackageUtils; +import android.content.pm.parsing.result.ParseInput; +import android.content.pm.parsing.result.ParseResult; +import android.content.pm.parsing.result.ParseTypeImpl; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.XmlResourceParser; @@ -116,6 +123,7 @@ import dalvik.system.VMRuntime; import libcore.util.EmptyArray; +import java.io.File; import java.lang.ref.WeakReference; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; @@ -2055,6 +2063,31 @@ public class ApplicationPackageManager extends PackageManager { return info.loadLabel(this); } + @Nullable + public PackageInfo getPackageArchiveInfo(@NonNull String archiveFilePath, + @PackageInfoFlags int flags) { + if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE + | PackageManager.MATCH_DIRECT_BOOT_AWARE)) == 0) { + // Caller expressed no opinion about what encryption + // aware/unaware components they want to see, so match both + flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; + } + + boolean collectCertificates = (flags & PackageManager.GET_SIGNATURES) != 0 + || (flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0; + + ParseInput input = ParseTypeImpl.forParsingWithoutPlatformCompat().reset(); + ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefault(input, + new File(archiveFilePath), 0, getPermissionManager().getSplitPermissions(), + collectCertificates); + if (result.isError()) { + return null; + } + return PackageInfoWithoutStateUtils.generate(result.getResult(), null, flags, 0, 0, null, + new PackageUserState(), UserHandle.getCallingUserId()); + } + @Override public int installExistingPackage(String packageName) throws NameNotFoundException { return installExistingPackage(packageName, INSTALL_REASON_UNKNOWN); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 72fb1cae3871..e01e530a8b97 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -48,12 +48,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.dex.ArtManager; -import android.content.pm.parsing.PackageInfoWithoutStateUtils; -import android.content.pm.parsing.ParsingPackage; -import android.content.pm.parsing.ParsingPackageUtils; -import android.content.pm.parsing.result.ParseInput; -import android.content.pm.parsing.result.ParseResult; -import android.content.pm.parsing.result.ParseTypeImpl; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.XmlResourceParser; @@ -83,7 +77,6 @@ import com.android.internal.util.ArrayUtils; import dalvik.system.VMRuntime; -import java.io.File; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.security.cert.Certificate; @@ -6791,25 +6784,8 @@ public abstract class PackageManager { @Nullable public PackageInfo getPackageArchiveInfo(@NonNull String archiveFilePath, @PackageInfoFlags int flags) { - if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE - | PackageManager.MATCH_DIRECT_BOOT_AWARE)) == 0) { - // Caller expressed no opinion about what encryption - // aware/unaware components they want to see, so match both - flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; - } - - boolean collectCertificates = (flags & PackageManager.GET_SIGNATURES) != 0 - || (flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0; - - ParseInput input = ParseTypeImpl.forParsingWithoutPlatformCompat().reset(); - ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefault(input, - new File(archiveFilePath), 0, collectCertificates); - if (result.isError()) { - return null; - } - return PackageInfoWithoutStateUtils.generate(result.getResult(), null, flags, 0, 0, null, - new PackageUserState(), UserHandle.getCallingUserId()); + throw new UnsupportedOperationException( + "getPackageArchiveInfo() not implemented in subclass"); } /** diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index b054304bbe74..8fbf2879bc27 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -34,7 +34,6 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleableRes; -import android.app.ActivityThread; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; @@ -222,13 +221,15 @@ public class ParsingPackageUtils { private static final int MAX_FILE_NAME_SIZE = 223; /** - * @see #parseDefault(ParseInput, File, int, boolean) + * @see #parseDefault(ParseInput, File, int, List, boolean) */ @NonNull public static ParseResult<ParsingPackage> parseDefaultOneTime(File file, - @ParseFlags int parseFlags, boolean collectCertificates) { + @ParseFlags int parseFlags, + @NonNull List<PermissionManager.SplitPermissionInfo> splitPermissions, + boolean collectCertificates) { ParseInput input = ParseTypeImpl.forDefaultParsing().reset(); - return parseDefault(input, file, parseFlags, collectCertificates); + return parseDefault(input, file, parseFlags, splitPermissions, collectCertificates); } /** @@ -238,28 +239,32 @@ public class ParsingPackageUtils { */ @NonNull public static ParseResult<ParsingPackage> parseDefault(ParseInput input, File file, - @ParseFlags int parseFlags, boolean collectCertificates) { + @ParseFlags int parseFlags, + @NonNull List<PermissionManager.SplitPermissionInfo> splitPermissions, + boolean collectCertificates) { ParseResult<ParsingPackage> result; - ParsingPackageUtils parser = new ParsingPackageUtils(false, null, null, new Callback() { - @Override - public boolean hasFeature(String feature) { - // Assume the device doesn't support anything. This will affect permission parsing - // and will force <uses-permission/> declarations to include all requiredNotFeature - // permissions and exclude all requiredFeature permissions. This mirrors the old - // behavior. - return false; - } - - @Override - public ParsingPackage startParsingPackage( - @NonNull String packageName, - @NonNull String baseApkPath, - @NonNull String path, - @NonNull TypedArray manifestArray, boolean isCoreApp) { - return new ParsingPackageImpl(packageName, baseApkPath, path, manifestArray); - } - }); + ParsingPackageUtils parser = new ParsingPackageUtils(false, null, null, splitPermissions, + new Callback() { + @Override + public boolean hasFeature(String feature) { + // Assume the device doesn't support anything. This will affect permission + // parsing and will force <uses-permission/> declarations to include all + // requiredNotFeature permissions and exclude all requiredFeature + // permissions. This mirrors the old behavior. + return false; + } + + @Override + public ParsingPackage startParsingPackage( + @NonNull String packageName, + @NonNull String baseApkPath, + @NonNull String path, + @NonNull TypedArray manifestArray, boolean isCoreApp) { + return new ParsingPackageImpl(packageName, baseApkPath, path, + manifestArray); + } + }); try { result = parser.parsePackage(input, file, parseFlags); if (result.isError()) { @@ -290,13 +295,18 @@ public class ParsingPackageUtils { private boolean mOnlyCoreApps; private String[] mSeparateProcesses; private DisplayMetrics mDisplayMetrics; + @NonNull + private List<PermissionManager.SplitPermissionInfo> mSplitPermissionInfos; private Callback mCallback; public ParsingPackageUtils(boolean onlyCoreApps, String[] separateProcesses, - DisplayMetrics displayMetrics, @NonNull Callback callback) { + DisplayMetrics displayMetrics, + @NonNull List<PermissionManager.SplitPermissionInfo> splitPermissions, + @NonNull Callback callback) { mOnlyCoreApps = onlyCoreApps; mSeparateProcesses = separateProcesses; mDisplayMetrics = displayMetrics; + mSplitPermissionInfos = splitPermissions; mCallback = callback; } @@ -2743,14 +2753,10 @@ public class ParsingPackageUtils { } } - private static void convertSplitPermissions(ParsingPackage pkg) { - final List<PermissionManager.SplitPermissionInfo> splitPermissions = - ActivityThread.currentApplication().getSystemService(PermissionManager.class) - .getSplitPermissions(); - - final int listSize = splitPermissions.size(); + private void convertSplitPermissions(ParsingPackage pkg) { + final int listSize = mSplitPermissionInfos.size(); for (int is = 0; is < listSize; is++) { - final PermissionManager.SplitPermissionInfo spi = splitPermissions.get(is); + final PermissionManager.SplitPermissionInfo spi = mSplitPermissionInfos.get(is); List<String> requestedPermissions = pkg.getRequestedPermissions(); if (pkg.getTargetSdkVersion() >= spi.getTargetSdk() || !requestedPermissions.contains(spi.getSplitPermission())) { diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java index 88faa0a49c9c..57c0be5007b8 100644 --- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java +++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java @@ -78,6 +78,7 @@ import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -334,7 +335,8 @@ public class PackageManagerTests extends AndroidTestCase { private ParsingPackage parsePackage(Uri packageURI) { final String archiveFilePath = packageURI.getPath(); ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefaultOneTime( - new File(archiveFilePath), 0 /*flags*/, false /*collectCertificates*/); + new File(archiveFilePath), 0 /*flags*/, Collections.emptyList(), + false /*collectCertificates*/); if (result.isError()) { throw new IllegalStateException(result.getErrorMessage(), result.getException()); } diff --git a/services/core/java/com/android/server/pm/parsing/PackageParser2.java b/services/core/java/com/android/server/pm/parsing/PackageParser2.java index 851ddd1eae48..e8be9b6fd82d 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageParser2.java +++ b/services/core/java/com/android/server/pm/parsing/PackageParser2.java @@ -19,6 +19,7 @@ package com.android.server.pm.parsing; import android.annotation.AnyThread; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityThread; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageParser; @@ -33,6 +34,7 @@ import android.content.res.TypedArray; import android.os.Build; import android.os.ServiceManager; import android.os.SystemClock; +import android.permission.PermissionManager; import android.util.DisplayMetrics; import android.util.Slog; @@ -42,6 +44,7 @@ import com.android.server.pm.parsing.pkg.PackageImpl; import com.android.server.pm.parsing.pkg.ParsedPackage; import java.io.File; +import java.util.List; /** * The v2 of {@link PackageParser} for use when parsing is initiated in the server and must @@ -118,10 +121,15 @@ public class PackageParser2 implements AutoCloseable { displayMetrics.setToDefaults(); } + PermissionManager permissionManager = ActivityThread.currentApplication() + .getSystemService(PermissionManager.class); + List<PermissionManager.SplitPermissionInfo> splitPermissions = permissionManager + .getSplitPermissions(); + mCacher = cacheDir == null ? null : new PackageCacher(cacheDir); parsingUtils = new ParsingPackageUtils(onlyCoreApps, separateProcesses, displayMetrics, - callback); + splitPermissions, callback); ParseInput.Callback enforcementCallback = (changeId, packageName, targetSdkVersion) -> { ApplicationInfo appInfo = mSharedAppInfo.get(); diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java index bb223b33d8aa..fb13d8707a44 100644 --- a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java @@ -55,6 +55,7 @@ import org.junit.runner.RunWith; import java.io.File; import java.io.InputStream; +import java.util.Collections; import java.util.function.Function; /** @@ -523,7 +524,7 @@ public class PackageParserLegacyCoreTest { int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES; ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefaultOneTime(apexFile, - flags, false /*collectCertificates*/); + flags, Collections.emptyList(), false /*collectCertificates*/); if (result.isError()) { throw new IllegalStateException(result.getErrorMessage(), result.getException()); } diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt index d8910dec0bcc..4dc9a90bf57c 100644 --- a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParsingDeferErrorTest.kt @@ -19,12 +19,10 @@ package com.android.server.pm.parsing import android.annotation.RawRes import android.content.Context import android.content.pm.parsing.ParsingPackage -import android.content.pm.parsing.ParsingPackageImpl import android.content.pm.parsing.ParsingPackageUtils import android.content.pm.parsing.result.ParseInput import android.content.pm.parsing.result.ParseInput.DeferredError import android.content.pm.parsing.result.ParseResult -import android.content.res.TypedArray import android.os.Build import androidx.test.InstrumentationRegistry import com.android.frameworks.servicestests.R @@ -130,7 +128,7 @@ class PackageParsingDeferErrorTest { input.copyTo(output) } } - return ParsingPackageUtils.parseDefaultOneTime(file, 0 /*flags*/, + return ParsingPackageUtils.parseDefaultOneTime(file, 0 /*flags*/, emptyList(), false /*collectCertificates*/) } } |