diff options
| author | 2023-12-20 06:22:57 +0000 | |
|---|---|---|
| committer | 2023-12-20 06:22:57 +0000 | |
| commit | 881ba1931c4043fcdee235f27e39c687076d1a85 (patch) | |
| tree | 14356d11a8d840fd0ce1dcbec07be73755dd5b25 | |
| parent | 13161419e7752460d59a557b3fabd49a5d13486d (diff) | |
| parent | 68f012f0fcb623137ef7f3cb3288d1f2f1e8514f (diff) | |
Merge "Move PackageParser2 to internal" into main
25 files changed, 193 insertions, 108 deletions
diff --git a/core/java/com/android/internal/pm/parsing/IPackageCacher.java b/core/java/com/android/internal/pm/parsing/IPackageCacher.java new file mode 100644 index 000000000000..3e01730ebab6 --- /dev/null +++ b/core/java/com/android/internal/pm/parsing/IPackageCacher.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.internal.pm.parsing; + +import com.android.internal.pm.parsing.pkg.ParsedPackage; + +import java.io.File; + +/** @hide */ +public interface IPackageCacher { + + /** + * Returns the cached parse result for {@code packageFile} for parse flags {@code flags}, + * or {@code null} if no cached result exists. + */ + ParsedPackage getCachedResult(File packageFile, int flags); + + /** + * Caches the parse result for {@code packageFile} with flags {@code flags}. + */ + void cacheResult(File packageFile, int flags, ParsedPackage parsed); +} diff --git a/services/core/java/com/android/server/pm/parsing/PackageParser2.java b/core/java/com/android/internal/pm/parsing/PackageParser2.java index b6a08a5a546f..e41329340000 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageParser2.java +++ b/core/java/com/android/internal/pm/parsing/PackageParser2.java @@ -14,13 +14,12 @@ * limitations under the License. */ -package com.android.server.pm.parsing; +package com.android.internal.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.parsing.PackageLite; import android.content.pm.parsing.result.ParseInput; @@ -28,26 +27,20 @@ import android.content.pm.parsing.result.ParseResult; import android.content.pm.parsing.result.ParseTypeImpl; 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; -import com.android.internal.compat.IPlatformCompat; import com.android.internal.pm.parsing.pkg.PackageImpl; import com.android.internal.pm.parsing.pkg.ParsedPackage; import com.android.internal.pm.pkg.parsing.ParsingPackage; import com.android.internal.pm.pkg.parsing.ParsingPackageUtils; import com.android.internal.pm.pkg.parsing.ParsingUtils; import com.android.internal.util.ArrayUtils; -import com.android.server.SystemConfig; -import com.android.server.pm.PackageManagerException; -import com.android.server.pm.PackageManagerService; import java.io.File; import java.util.List; -import java.util.Set; /** * The v2 of package parsing for use when parsing is initiated in the server and must @@ -59,50 +52,6 @@ import java.util.Set; */ public class PackageParser2 implements AutoCloseable { - /** - * For parsing inside the system server but outside of {@link PackageManagerService}. - * Generally used for parsing information in an APK that hasn't been installed yet. - * - * This must be called inside the system process as it relies on {@link ServiceManager}. - */ - @NonNull - public static PackageParser2 forParsingFileWithDefaults() { - IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface( - ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); - return new PackageParser2(null /* separateProcesses */, null /* displayMetrics */, - null /* cacheDir */, new Callback() { - @Override - public boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo) { - try { - return platformCompat.isChangeEnabled(changeId, appInfo); - } catch (Exception e) { - // This shouldn't happen, but assume enforcement if it does - Slog.wtf(TAG, "IPlatformCompat query failed", e); - return true; - } - } - - @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 Set<String> getHiddenApiWhitelistedApps() { - return SystemConfig.getInstance().getHiddenApiWhitelistedApps(); - } - - @Override - public Set<String> getInstallConstraintsAllowlist() { - return SystemConfig.getInstance().getInstallConstraintsAllowlist(); - } - }); - } - private static final String TAG = ParsingUtils.TAG; private static final boolean LOG_PARSE_TIMINGS = Build.IS_DEBUGGABLE; @@ -118,12 +67,12 @@ public class PackageParser2 implements AutoCloseable { private final ThreadLocal<ParseTypeImpl> mSharedResult; @Nullable - protected PackageCacher mCacher; + protected IPackageCacher mCacher; - private final ParsingPackageUtils parsingUtils; + private final ParsingPackageUtils mParsingUtils; public PackageParser2(String[] separateProcesses, DisplayMetrics displayMetrics, - @Nullable File cacheDir, @NonNull Callback callback) { + @Nullable IPackageCacher cacher, @NonNull Callback callback) { if (displayMetrics == null) { displayMetrics = new DisplayMetrics(); displayMetrics.setToDefaults(); @@ -134,9 +83,9 @@ public class PackageParser2 implements AutoCloseable { List<PermissionManager.SplitPermissionInfo> splitPermissions = permissionManager .getSplitPermissions(); - mCacher = cacheDir == null ? null : new PackageCacher(cacheDir); + mCacher = cacher; - parsingUtils = new ParsingPackageUtils(separateProcesses, displayMetrics, splitPermissions, + mParsingUtils = new ParsingPackageUtils(separateProcesses, displayMetrics, splitPermissions, callback); ParseInput.Callback enforcementCallback = (changeId, packageName, targetSdkVersion) -> { @@ -155,7 +104,7 @@ public class PackageParser2 implements AutoCloseable { */ @AnyThread public ParsedPackage parsePackage(File packageFile, int flags, boolean useCaches) - throws PackageManagerException { + throws PackageParserException { var files = packageFile.listFiles(); // Apk directory is directly nested under the current directory if (ArrayUtils.size(files) == 1 && files[0].isDirectory()) { @@ -171,9 +120,9 @@ public class PackageParser2 implements AutoCloseable { long parseTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0; ParseInput input = mSharedResult.get().reset(); - ParseResult<ParsingPackage> result = parsingUtils.parsePackage(input, packageFile, flags); + ParseResult<ParsingPackage> result = mParsingUtils.parsePackage(input, packageFile, flags); if (result.isError()) { - throw new PackageManagerException(result.getErrorCode(), result.getErrorMessage(), + throw new PackageParserException(result.getErrorCode(), result.getErrorMessage(), result.getException()); } @@ -201,12 +150,12 @@ public class PackageParser2 implements AutoCloseable { */ @AnyThread public ParsedPackage parsePackageFromPackageLite(PackageLite packageLite, int flags) - throws PackageManagerException { + throws PackageParserException { ParseInput input = mSharedResult.get().reset(); - ParseResult<ParsingPackage> result = parsingUtils.parsePackageFromPackageLite(input, + ParseResult<ParsingPackage> result = mParsingUtils.parsePackageFromPackageLite(input, packageLite, flags); if (result.isError()) { - throw new PackageManagerException(result.getErrorCode(), result.getErrorMessage(), + throw new PackageParserException(result.getErrorCode(), result.getErrorMessage(), result.getException()); } return result.getResult().hideAsParsed(); @@ -226,7 +175,7 @@ public class PackageParser2 implements AutoCloseable { mSharedAppInfo.remove(); } - public static abstract class Callback implements ParsingPackageUtils.Callback { + public abstract static class Callback implements ParsingPackageUtils.Callback { @Override public final ParsingPackage startParsingPackage(@NonNull String packageName, diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java index f2dcba45e312..5514ec701c15 100644 --- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java +++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java @@ -59,6 +59,7 @@ import android.util.apk.SourceStampVerifier; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.pm.parsing.PackageParser2; import com.android.internal.pm.pkg.parsing.ParsingPackageUtils; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FrameworkStatsLog; @@ -67,7 +68,7 @@ import com.android.server.integrity.engine.RuleEvaluationEngine; import com.android.server.integrity.model.IntegrityCheckResult; import com.android.server.integrity.model.RuleMetadata; import com.android.server.pm.PackageManagerServiceUtils; -import com.android.server.pm.parsing.PackageParser2; +import com.android.server.pm.parsing.PackageParserUtils; import java.io.ByteArrayInputStream; import java.io.File; @@ -141,7 +142,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub { return new AppIntegrityManagerServiceImpl( context, LocalServices.getService(PackageManagerInternal.class), - PackageParser2::forParsingFileWithDefaults, + PackageParserUtils::forParsingFileWithDefaults, RuleEvaluationEngine.getRuleEvaluationEngine(), IntegrityFileManager.getInstance(), handlerThread.getThreadHandler()); diff --git a/services/core/java/com/android/server/pm/InitAppsHelper.java b/services/core/java/com/android/server/pm/InitAppsHelper.java index 3b9f9c804e27..41d01762505d 100644 --- a/services/core/java/com/android/server/pm/InitAppsHelper.java +++ b/services/core/java/com/android/server/pm/InitAppsHelper.java @@ -46,11 +46,11 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.om.OverlayConfig; +import com.android.internal.pm.parsing.PackageParser2; import com.android.internal.pm.pkg.parsing.ParsingPackageUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.server.EventLogTags; import com.android.server.pm.parsing.PackageCacher; -import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.utils.WatchedArrayMap; diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index 65bfb2f258eb..8b38f947b952 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -146,6 +146,7 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.EventLog; +import android.util.ExceptionUtils; import android.util.Log; import android.util.Pair; import android.util.Slog; @@ -154,6 +155,7 @@ import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.content.F2fsUtils; +import com.android.internal.pm.parsing.PackageParser2; import com.android.internal.pm.parsing.PackageParserException; import com.android.internal.pm.parsing.pkg.AndroidPackageLegacyUtils; import com.android.internal.pm.parsing.pkg.ParsedPackage; @@ -178,7 +180,6 @@ import com.android.server.pm.dex.ArtManagerService; import com.android.server.pm.dex.DexManager; import com.android.server.pm.dex.DexoptOptions; import com.android.server.pm.parsing.PackageCacher; -import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.parsing.pkg.AndroidPackageUtils; import com.android.server.pm.permission.Permission; import com.android.server.pm.permission.PermissionManagerServiceInternal; @@ -1167,8 +1168,9 @@ final class InstallPackageHelper { parseFlags); archivedPackage = request.getPackageLite().getArchivedPackage(); } - } catch (PackageManagerException | PackageParserException e) { - throw new PrepareFailure("Failed parse during installPackageLI", e); + } catch (PackageParserException e) { + throw new PrepareFailure(e.error, + ExceptionUtils.getCompleteMessage("Failed parse during installPackageLI", e)); } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } @@ -3680,6 +3682,8 @@ final class InstallPackageHelper { final ParsedPackage parsedPackage; try (PackageParser2 pp = mPm.mInjector.getScanningPackageParser()) { parsedPackage = pp.parsePackage(scanFile, parseFlags, false); + } catch (PackageParserException e) { + throw new PackageManagerException(e.error, e.getMessage(), e); } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } diff --git a/services/core/java/com/android/server/pm/InstallingSession.java b/services/core/java/com/android/server/pm/InstallingSession.java index 187cadaf4d46..e970d2c79b05 100644 --- a/services/core/java/com/android/server/pm/InstallingSession.java +++ b/services/core/java/com/android/server/pm/InstallingSession.java @@ -51,8 +51,8 @@ import android.util.Slog; import com.android.internal.content.F2fsUtils; import com.android.internal.content.InstallLocationUtils; import com.android.internal.content.NativeLibraryHelper; +import com.android.internal.pm.parsing.PackageParser2; import com.android.internal.util.Preconditions; -import com.android.server.pm.parsing.PackageParser2; import libcore.io.IoUtils; diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 2942bbb86e62..cbd65a4eb936 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -111,6 +111,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.InstallLocationUtils; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; +import com.android.internal.pm.parsing.PackageParser2; import com.android.internal.util.ImageUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.modules.utils.TypedXmlPullParser; @@ -120,7 +121,6 @@ import com.android.server.LocalServices; import com.android.server.SystemConfig; import com.android.server.SystemService; import com.android.server.SystemServiceManager; -import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.pkg.PackageStateInternal; import com.android.server.pm.utils.RequestThrottle; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 1d5b8c3ed22a..81d5d8195960 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -181,6 +181,7 @@ import com.android.internal.app.ResolverActivity; import com.android.internal.content.F2fsUtils; import com.android.internal.content.InstallLocationUtils; import com.android.internal.content.om.OverlayConfig; +import com.android.internal.pm.parsing.PackageParser2; import com.android.internal.pm.parsing.pkg.AndroidPackageInternal; import com.android.internal.pm.parsing.pkg.ParsedPackage; import com.android.internal.pm.pkg.component.ParsedInstrumentation; @@ -221,8 +222,8 @@ import com.android.server.pm.dex.ArtUtils; import com.android.server.pm.dex.DexManager; import com.android.server.pm.dex.DynamicCodeLogger; import com.android.server.pm.local.PackageManagerLocalImpl; +import com.android.server.pm.parsing.PackageCacher; import com.android.server.pm.parsing.PackageInfoUtils; -import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.parsing.pkg.AndroidPackageUtils; import com.android.server.pm.permission.LegacyPermissionManagerInternal; import com.android.server.pm.permission.LegacyPermissionManagerService; @@ -1698,7 +1699,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService () -> LocalServices.getService(UserManagerInternal.class)), (i, pm) -> new DisplayMetrics(), (i, pm) -> new PackageParser2(pm.mSeparateProcesses, i.getDisplayMetrics(), - pm.mCacheDir, + new PackageCacher(pm.mCacheDir), pm.mPackageParserCallback) /* scanningCachingPackageParserProducer */, (i, pm) -> new PackageParser2(pm.mSeparateProcesses, i.getDisplayMetrics(), null, pm.mPackageParserCallback) /* scanningPackageParserProducer */, diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java index ebf1c04bee12..049737d42f51 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java @@ -27,12 +27,12 @@ import android.os.incremental.IncrementalManager; import android.util.DisplayMetrics; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.pm.parsing.PackageParser2; import com.android.server.SystemConfig; import com.android.server.compat.PlatformCompat; import com.android.server.pm.dex.ArtManagerService; import com.android.server.pm.dex.DexManager; import com.android.server.pm.dex.DynamicCodeLogger; -import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.permission.LegacyPermissionManagerInternal; import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.pm.resolution.ComponentResolver; diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java b/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java index 655b9c93d9dd..86d78dce96c3 100644 --- a/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java +++ b/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java @@ -31,10 +31,10 @@ import android.util.DisplayMetrics; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.om.OverlayConfig; +import com.android.internal.pm.parsing.PackageParser2; import com.android.server.pm.dex.ArtManagerService; import com.android.server.pm.dex.DexManager; import com.android.server.pm.dex.DynamicCodeLogger; -import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.permission.LegacyPermissionManagerInternal; import com.android.server.pm.pkg.AndroidPackage; diff --git a/services/core/java/com/android/server/pm/PackageSessionVerifier.java b/services/core/java/com/android/server/pm/PackageSessionVerifier.java index 15d2fdc35f2b..1fe49c7d5834 100644 --- a/services/core/java/com/android/server/pm/PackageSessionVerifier.java +++ b/services/core/java/com/android/server/pm/PackageSessionVerifier.java @@ -41,10 +41,11 @@ import android.util.apk.ApkSignatureVerifier; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.InstallLocationUtils; +import com.android.internal.pm.parsing.PackageParser2; +import com.android.internal.pm.parsing.PackageParserException; import com.android.internal.pm.parsing.pkg.ParsedPackage; import com.android.server.LocalServices; import com.android.server.SystemConfig; -import com.android.server.pm.parsing.PackageParser2; import com.android.server.rollback.RollbackManagerInternal; import java.io.File; @@ -399,7 +400,7 @@ final class PackageSessionVerifier { try (PackageParser2 packageParser = mPackageParserSupplier.get()) { File apexFile = new File(apexInfo.modulePath); parsedPackage = packageParser.parsePackage(apexFile, 0, false); - } catch (PackageManagerException e) { + } catch (PackageParserException e) { throw new PackageManagerException( PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE, "Failed to parse APEX package " + apexInfo.modulePath + " : " + e, e); diff --git a/services/core/java/com/android/server/pm/ParallelPackageParser.java b/services/core/java/com/android/server/pm/ParallelPackageParser.java index 1089ac943802..051163925b16 100644 --- a/services/core/java/com/android/server/pm/ParallelPackageParser.java +++ b/services/core/java/com/android/server/pm/ParallelPackageParser.java @@ -22,9 +22,10 @@ import android.os.Process; import android.os.Trace; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.pm.parsing.PackageParser2; +import com.android.internal.pm.parsing.PackageParserException; import com.android.internal.pm.parsing.pkg.ParsedPackage; import com.android.internal.util.ConcurrentUtils; -import com.android.server.pm.parsing.PackageParser2; import java.io.File; import java.util.concurrent.ArrayBlockingQueue; @@ -125,6 +126,10 @@ class ParallelPackageParser { @VisibleForTesting protected ParsedPackage parsePackage(File scanFile, int parseFlags) throws PackageManagerException { - return mPackageParser.parsePackage(scanFile, parseFlags, true); + try { + return mPackageParser.parsePackage(scanFile, parseFlags, true); + } catch (PackageParserException e) { + throw new PackageManagerException(e.error, e.getMessage(), e); + } } } diff --git a/services/core/java/com/android/server/pm/parsing/PackageCacher.java b/services/core/java/com/android/server/pm/parsing/PackageCacher.java index 79c9c8ec8b0b..b6267c499c07 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageCacher.java +++ b/services/core/java/com/android/server/pm/parsing/PackageCacher.java @@ -28,6 +28,7 @@ import android.system.StructStat; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.pm.parsing.IPackageCacher; import com.android.internal.pm.parsing.pkg.PackageImpl; import com.android.internal.pm.parsing.pkg.ParsedPackage; import com.android.server.pm.ApexManager; @@ -39,7 +40,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.concurrent.atomic.AtomicInteger; -public class PackageCacher { +public class PackageCacher implements IPackageCacher { private static final String TAG = "PackageCacher"; @@ -162,6 +163,7 @@ public class PackageCacher { * Returns the cached parse result for {@code packageFile} for parse flags {@code flags}, * or {@code null} if no cached result exists. */ + @Override public ParsedPackage getCachedResult(File packageFile, int flags) { final String cacheKey = getCacheKey(packageFile, flags); final File cacheFile = new File(mCacheDir, cacheKey); @@ -192,6 +194,7 @@ public class PackageCacher { /** * Caches the parse result for {@code packageFile} with flags {@code flags}. */ + @Override public void cacheResult(File packageFile, int flags, ParsedPackage parsed) { try { final String cacheKey = getCacheKey(packageFile, flags); diff --git a/services/core/java/com/android/server/pm/parsing/PackageParserUtils.java b/services/core/java/com/android/server/pm/parsing/PackageParserUtils.java new file mode 100644 index 000000000000..03a7a37a550c --- /dev/null +++ b/services/core/java/com/android/server/pm/parsing/PackageParserUtils.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.pm.parsing; + +import android.annotation.NonNull; +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.os.ServiceManager; +import android.util.Slog; + +import com.android.internal.compat.IPlatformCompat; +import com.android.internal.pm.parsing.PackageParser2; +import com.android.internal.pm.pkg.parsing.ParsingUtils; +import com.android.server.SystemConfig; +import com.android.server.pm.PackageManagerService; + +import java.util.Set; + +public class PackageParserUtils { + /** + * For parsing inside the system server but outside of {@link PackageManagerService}. + * Generally used for parsing information in an APK that hasn't been installed yet. + * + * This must be called inside the system process as it relies on {@link ServiceManager}. + */ + @NonNull + @SuppressLint("AndroidFrameworkRequiresPermission") + public static PackageParser2 forParsingFileWithDefaults() { + IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface( + ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); + return new PackageParser2(null /* separateProcesses */, null /* displayMetrics */, + null /* cacheDir */, new PackageParser2.Callback() { + @Override + @SuppressLint("AndroidFrameworkRequiresPermission") + public boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo) { + try { + return platformCompat.isChangeEnabled(changeId, appInfo); + } catch (Exception e) { + // This shouldn't happen, but assume enforcement if it does + Slog.wtf(ParsingUtils.TAG, "IPlatformCompat query failed", e); + return true; + } + } + + @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 Set<String> getHiddenApiWhitelistedApps() { + return SystemConfig.getInstance().getHiddenApiWhitelistedApps(); + } + + @Override + public Set<String> getInstallConstraintsAllowlist() { + return SystemConfig.getInstance().getInstallConstraintsAllowlist(); + } + }); + } +} 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 03e45a27390f..71f5c754f22f 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 @@ -58,6 +58,8 @@ import androidx.test.filters.MediumTest; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.pm.parsing.PackageParser2; +import com.android.internal.pm.parsing.PackageParserException; import com.android.internal.pm.parsing.pkg.PackageImpl; import com.android.internal.pm.parsing.pkg.ParsedPackage; import com.android.internal.pm.permission.CompatibilityPermissionInfo; @@ -84,7 +86,7 @@ import com.android.internal.pm.pkg.parsing.ParsingPackage; import com.android.internal.util.ArrayUtils; import com.android.server.pm.parsing.PackageCacher; import com.android.server.pm.parsing.PackageInfoUtils; -import com.android.server.pm.parsing.PackageParser2; +import com.android.server.pm.parsing.PackageParserUtils; import com.android.server.pm.parsing.TestPackageParser2; import com.android.server.pm.parsing.pkg.AndroidPackageUtils; import com.android.server.pm.pkg.AndroidPackage; @@ -185,7 +187,7 @@ public class PackageParserTest { @Test public void test_serializePackage() throws Exception { - try (PackageParser2 pp = PackageParser2.forParsingFileWithDefaults()) { + try (PackageParser2 pp = PackageParserUtils.forParsingFileWithDefaults()) { AndroidPackage pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */).hideAsFinal(); @@ -363,7 +365,7 @@ public class PackageParserTest { actualDisplayCategory = activity.getRequiredDisplayCategory(); } } - } catch (PackageManagerException e) { + } catch (PackageParserException e) { assertThat(e.getMessage()).contains( "requiredDisplayCategory attribute can only consist" + " of alphanumeric characters, '_', and '.'"); diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ParallelPackageParserTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ParallelPackageParserTest.java index 8a74e24a3810..376124049c4c 100644 --- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ParallelPackageParserTest.java +++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ParallelPackageParserTest.java @@ -21,8 +21,8 @@ import android.util.Log; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.pm.parsing.PackageParser2; import com.android.internal.pm.parsing.pkg.ParsedPackage; -import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.parsing.TestPackageParser2; import junit.framework.Assert; diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java index b63950c10a18..a28b28a49162 100644 --- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java +++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java @@ -38,6 +38,7 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.pm.parsing.PackageParserException; import com.android.internal.pm.parsing.pkg.ParsedPackage; import com.android.internal.pm.pkg.component.ParsedActivityUtils; import com.android.internal.pm.pkg.component.ParsedComponent; @@ -45,7 +46,6 @@ import com.android.internal.pm.pkg.component.ParsedIntentInfo; import com.android.internal.pm.pkg.component.ParsedPermission; import com.android.internal.pm.pkg.component.ParsedPermissionUtils; import com.android.internal.util.ArrayUtils; -import com.android.server.pm.PackageManagerException; import com.android.server.pm.pkg.AndroidPackage; import com.android.server.pm.test.service.server.R; @@ -608,7 +608,7 @@ public class PackageParserLegacyCoreTest { try { parsePackage(filename, resId, x -> x); expect.withMessage("Expected parsing error %s from %s", result, filename).fail(); - } catch (PackageManagerException expected) { + } catch (PackageParserException expected) { expect.that(expected.error).isEqualTo(result); } } diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt index 98af63c65e90..1d668cd3e8f2 100644 --- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt +++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/parsing/SystemPartitionParseTest.kt @@ -18,8 +18,8 @@ package com.android.server.pm.parsing import android.content.pm.PackageManager import android.platform.test.annotations.Postsubmit +import com.android.internal.pm.parsing.PackageParserException import com.android.internal.pm.pkg.parsing.ParsingPackageUtils -import com.android.server.pm.PackageManagerException import com.android.server.pm.PackageManagerService import com.android.server.pm.PackageManagerServiceUtils import java.io.File @@ -39,7 +39,7 @@ import org.junit.rules.TemporaryFolder @Postsubmit class SystemPartitionParseTest { - private val parser = PackageParser2.forParsingFileWithDefaults() + private val parser = PackageParserUtils.forParsingFileWithDefaults() @get:Rule val tempFolder = TemporaryFolder() @@ -86,7 +86,7 @@ class SystemPartitionParseTest { } } .mapNotNull { it.exceptionOrNull() } - .filterNot { (it as? PackageManagerException)?.error == + .filterNot { (it as? PackageParserException)?.error == PackageManager.INSTALL_PARSE_FAILED_SKIPPED } if (exceptions.isEmpty()) return diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java index c2b52b4ee9c8..57326b2e1e82 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java @@ -50,9 +50,10 @@ import android.util.ArraySet; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.pm.parsing.PackageParser2; +import com.android.internal.pm.parsing.PackageParserException; import com.android.internal.pm.parsing.pkg.AndroidPackageLegacyUtils; import com.android.internal.pm.pkg.parsing.ParsingPackageUtils; -import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.pkg.AndroidPackage; import org.junit.Before; @@ -175,7 +176,7 @@ public class ApexManagerTest { mPmService.getPlatformPackage(), /* isUpdatedSystemApp */ false); // isUpdatedSystemApp is ignoreable above, only used for shared library adjustment return parsedPackage.hideAsFinal(); - } catch (PackageManagerException e) { + } catch (PackageParserException e) { throw new RuntimeException(e); } } 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 7b29e2a4159d..538c0ee52424 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt @@ -56,6 +56,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.spy import com.android.dx.mockito.inline.extended.StaticMockitoSession import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder import com.android.internal.R +import com.android.internal.pm.parsing.PackageParser2 import com.android.internal.pm.parsing.pkg.PackageImpl import com.android.internal.pm.parsing.pkg.ParsedPackage import com.android.internal.pm.pkg.parsing.ParsingPackage @@ -69,7 +70,6 @@ import com.android.server.compat.PlatformCompat import com.android.server.extendedtestutils.wheneverStatic import com.android.server.pm.dex.DexManager import com.android.server.pm.dex.DynamicCodeLogger -import com.android.server.pm.parsing.PackageParser2 import com.android.server.pm.permission.PermissionManagerServiceInternal import com.android.server.pm.pkg.AndroidPackage import com.android.server.pm.resolution.ComponentResolver diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceBootTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceBootTest.kt index da929af3267b..7feafef4e489 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceBootTest.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageManagerServiceBootTest.kt @@ -21,6 +21,7 @@ import android.content.pm.PackageManager import android.os.Build import android.os.Process import android.util.Log +import com.android.internal.pm.parsing.PackageParserException import com.android.server.pm.pkg.AndroidPackage import com.android.server.testutils.whenever import java.io.File @@ -120,7 +121,7 @@ class PackageManagerServiceBootTest { argThat { path: File -> path.path.contains("a.data.package") }, anyInt(), anyBoolean())) - .thenThrow(PackageManagerException( + .thenThrow(PackageParserException( PackageManager.INSTALL_FAILED_INVALID_APK, "Oh no!")) val pm = createPackageManagerService() verify(rule.mocks().settings, Mockito.never()).insertPackageSettingLPw( diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java index ce15c6d30531..eb9cce007b77 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java @@ -67,10 +67,10 @@ import android.provider.Settings; import androidx.test.InstrumentationRegistry; import com.android.internal.R; +import com.android.internal.pm.parsing.PackageParser2; import com.android.server.compat.PlatformCompat; import com.android.server.integrity.engine.RuleEvaluationEngine; import com.android.server.integrity.model.IntegrityCheckResult; -import com.android.server.pm.parsing.PackageParser2; import com.android.server.pm.parsing.TestPackageParser2; import com.android.server.testutils.TestUtils; diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java index 1bfd43ff60ef..25eedf5652d7 100644 --- a/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexMetadataHelperTest.java @@ -37,6 +37,7 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.frameworks.servicestests.R; +import com.android.internal.pm.parsing.PackageParserException; import com.android.internal.pm.parsing.pkg.ParsedPackage; import com.android.server.pm.PackageManagerException; import com.android.server.pm.parsing.TestPackageParser2; @@ -161,7 +162,8 @@ public class DexMetadataHelperTest { } @Test - public void testParsePackageWithDmFileValid() throws IOException, PackageManagerException { + public void testParsePackageWithDmFileValid() throws IOException, PackageManagerException, + PackageParserException { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); createDexMetadataFile("install_split_base.apk"); ParsedPackage pkg = new TestPackageParser2().parsePackage(mTmpDir, /*flags=*/0, false); @@ -178,7 +180,7 @@ public class DexMetadataHelperTest { @Test public void testParsePackageSplitsWithDmFileValid() - throws IOException, PackageManagerException { + throws IOException, PackageManagerException, PackageParserException { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); copyApkToToTmpDir("install_split_feature_a.apk", R.raw.install_split_feature_a); createDexMetadataFile("install_split_base.apk"); @@ -201,7 +203,7 @@ public class DexMetadataHelperTest { @Test public void testParsePackageSplitsNoBaseWithDmFileValid() - throws IOException, PackageManagerException { + throws IOException, PackageManagerException, PackageParserException { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); copyApkToToTmpDir("install_split_feature_a.apk", R.raw.install_split_feature_a); createDexMetadataFile("install_split_feature_a.apk"); @@ -219,7 +221,7 @@ public class DexMetadataHelperTest { } @Test - public void testParsePackageWithDmFileInvalid() throws IOException { + public void testParsePackageWithDmFileInvalid() throws IOException, PackageParserException { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); File invalidDmFile = new File(mTmpDir, "install_split_base.dm"); Files.createFile(invalidDmFile.toPath()); @@ -242,7 +244,7 @@ public class DexMetadataHelperTest { @Test public void testParsePackageSplitsWithDmFileInvalid() - throws IOException, PackageManagerException { + throws IOException, PackageParserException { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); copyApkToToTmpDir("install_split_feature_a.apk", R.raw.install_split_feature_a); createDexMetadataFile("install_split_base.apk"); @@ -268,7 +270,7 @@ public class DexMetadataHelperTest { @Test public void testParsePackageWithDmFileInvalidManifest() - throws IOException, PackageManagerException { + throws IOException, PackageParserException { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); createDexMetadataFile("install_split_base.apk", /*validManifest=*/false); @@ -283,7 +285,7 @@ public class DexMetadataHelperTest { @Test public void testParsePackageWithDmFileEmptyManifest() - throws IOException, PackageManagerException { + throws IOException, PackageParserException { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); createDexMetadataFile("install_split_base.apk", /*packageName=*/"doesn't matter", /*versionCode=*/-12345L, /*emptyManifest=*/true, /*validManifest=*/true); @@ -299,7 +301,7 @@ public class DexMetadataHelperTest { @Test public void testParsePackageWithDmFileBadPackageName() - throws IOException, PackageManagerException { + throws IOException, PackageParserException { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); createDexMetadataFile("install_split_base.apk", /*packageName=*/"bad package name", DEX_METADATA_VERSION_CODE, /*emptyManifest=*/false, /*validManifest=*/true); @@ -315,7 +317,7 @@ public class DexMetadataHelperTest { @Test public void testParsePackageWithDmFileBadVersionCode() - throws IOException, PackageManagerException { + throws IOException, PackageParserException { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); createDexMetadataFile("install_split_base.apk", DEX_METADATA_PACKAGE_NAME, /*versionCode=*/12345L, /*emptyManifest=*/false, /*validManifest=*/true); @@ -331,7 +333,7 @@ public class DexMetadataHelperTest { @Test public void testParsePackageWithDmFileMissingPackageName() - throws IOException, PackageManagerException { + throws IOException, PackageParserException { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); createDexMetadataFile("install_split_base.apk", /*packageName=*/null, DEX_METADATA_VERSION_CODE, /*emptyManifest=*/false, /*validManifest=*/true); @@ -347,7 +349,7 @@ public class DexMetadataHelperTest { @Test public void testParsePackageWithDmFileMissingVersionCode() - throws IOException, PackageManagerException { + throws IOException, PackageParserException { copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base); createDexMetadataFile("install_split_base.apk", DEX_METADATA_PACKAGE_NAME, /*versionCode=*/null, /*emptyManifest=*/false, /*validManifest=*/true); diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingValidationTest.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingValidationTest.kt index 9b4ca2a86f2c..6a088d99588e 100644 --- a/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingValidationTest.kt +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/AndroidPackageParsingValidationTest.kt @@ -36,7 +36,7 @@ import org.xmlpull.v1.XmlPullParserFactory @Postsubmit class AndroidPackageParsingValidationTest { companion object { - private val parser2 = PackageParser2.forParsingFileWithDefaults() + private val parser2 = PackageParserUtils.forParsingFileWithDefaults() private val apks = ((PackageManagerService.SYSTEM_PARTITIONS) .flatMap { listOfNotNull(it.privAppFolder, it.appFolder, it.overlayFolder) diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/TestPackageParser2.kt b/services/tests/servicestests/src/com/android/server/pm/parsing/TestPackageParser2.kt index c44f583a93ef..e420e4b52b6e 100644 --- a/services/tests/servicestests/src/com/android/server/pm/parsing/TestPackageParser2.kt +++ b/services/tests/servicestests/src/com/android/server/pm/parsing/TestPackageParser2.kt @@ -18,11 +18,12 @@ package com.android.server.pm.parsing import android.content.pm.ApplicationInfo import android.util.ArraySet +import com.android.internal.pm.parsing.PackageParser2 import java.io.File class TestPackageParser2(var cacheDir: File? = null) : PackageParser2( null /* separateProcesses */, null /* displayMetrics */, - cacheDir /* cacheDir */, object : PackageParser2.Callback() { + cacheDir?.let { PackageCacher(cacheDir) }, object : PackageParser2.Callback() { override fun isChangeEnabled(changeId: Long, appInfo: ApplicationInfo): Boolean { return true } |