Loading core/java/com/android/internal/pm/parsing/IPackageCacher.java 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * 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); } services/core/java/com/android/server/pm/parsing/PackageParser2.java→core/java/com/android/internal/pm/parsing/PackageParser2.java +13 −64 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -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; Loading @@ -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(); Loading @@ -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) -> { Loading @@ -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()) { Loading @@ -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()); } Loading Loading @@ -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(); Loading @@ -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, Loading services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java +3 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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()); Loading services/core/java/com/android/server/pm/InitAppsHelper.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading services/core/java/com/android/server/pm/InstallPackageHelper.java +7 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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); } Loading Loading
core/java/com/android/internal/pm/parsing/IPackageCacher.java 0 → 100644 +35 −0 Original line number Diff line number Diff line /* * 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); }
services/core/java/com/android/server/pm/parsing/PackageParser2.java→core/java/com/android/internal/pm/parsing/PackageParser2.java +13 −64 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -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; Loading @@ -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(); Loading @@ -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) -> { Loading @@ -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()) { Loading @@ -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()); } Loading Loading @@ -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(); Loading @@ -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, Loading
services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java +3 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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()); Loading
services/core/java/com/android/server/pm/InitAppsHelper.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
services/core/java/com/android/server/pm/InstallPackageHelper.java +7 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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); } Loading