Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 881ba193 authored by TYM Tsai's avatar TYM Tsai Committed by Android (Google) Code Review
Browse files

Merge "Move PackageParser2 to internal" into main

parents 13161419 68f012f0
Loading
Loading
Loading
Loading
+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);
}
+13 −64
Original line number Diff line number Diff line
@@ -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,
+3 −2
Original line number Diff line number Diff line
@@ -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());
+1 −1
Original line number Diff line number Diff line
@@ -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;

+7 −3
Original line number Diff line number Diff line
@@ -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);
        }
Loading