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

Commit 9654d80a authored by Oli Lan's avatar Oli Lan Committed by Android (Google) Code Review
Browse files

Merge "Clean up generatePackageInfoFromApex() API"

parents 6538dbfa c2c7a223
Loading
Loading
Loading
Loading
+57 −73
Original line number Original line Diff line number Diff line
@@ -620,21 +620,6 @@ public class PackageParser {
        return path.endsWith(APK_FILE_EXTENSION);
        return path.endsWith(APK_FILE_EXTENSION);
    }
    }


    /**
     * Generate and return the {@link PackageInfo} for a parsed package.
     *
     * @param p the parsed package.
     * @param flags indicating which optional information is included.
     */
    @UnsupportedAppUsage
    public static PackageInfo generatePackageInfo(PackageParser.Package p,
            int gids[], int flags, long firstInstallTime, long lastUpdateTime,
            Set<String> grantedPermissions, PackageUserState state) {

        return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime,
                grantedPermissions, state, UserHandle.getCallingUserId());
    }

    /**
    /**
     * Returns true if the package is installed and not hidden, or if the caller
     * Returns true if the package is installed and not hidden, or if the caller
     * explicitly wanted all uninstalled and hidden packages as well.
     * explicitly wanted all uninstalled and hidden packages as well.
@@ -661,8 +646,45 @@ public class PackageParser {
        return checkUseInstalledOrHidden(0, state, null);
        return checkUseInstalledOrHidden(0, state, null);
    }
    }


    /**
     * Generate and return the {@link PackageInfo} for a parsed package.
     *
     * @param p the parsed package.
     * @param flags indicating which optional information is included.
     */
    @UnsupportedAppUsage
    @UnsupportedAppUsage
    public static PackageInfo generatePackageInfo(PackageParser.Package p,
    public static PackageInfo generatePackageInfo(PackageParser.Package p,
            int[] gids, int flags, long firstInstallTime, long lastUpdateTime,
            Set<String> grantedPermissions, PackageUserState state) {

        return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime,
                grantedPermissions, state, UserHandle.getCallingUserId());
    }

    @UnsupportedAppUsage
    public static PackageInfo generatePackageInfo(PackageParser.Package p,
            int[] gids, int flags, long firstInstallTime, long lastUpdateTime,
            Set<String> grantedPermissions, PackageUserState state, int userId) {

        return generatePackageInfo(p, null, gids, flags, firstInstallTime, lastUpdateTime,
                grantedPermissions, state, userId);
    }

    /**
     * PackageInfo generator specifically for apex files.
     *
     * @param pkg Package to generate info from. Should be derived from an apex.
     * @param apexInfo Apex info relating to the package.
     * @return PackageInfo
     * @throws PackageParserException
     */
    public static PackageInfo generatePackageInfo(
            PackageParser.Package pkg, ApexInfo apexInfo, int flags) {
        return generatePackageInfo(pkg, apexInfo, EmptyArray.INT, flags, 0, 0,
                Collections.emptySet(), new PackageUserState(), UserHandle.getCallingUserId());
    }

    private static PackageInfo generatePackageInfo(PackageParser.Package p, ApexInfo apexInfo,
            int gids[], int flags, long firstInstallTime, long lastUpdateTime,
            int gids[], int flags, long firstInstallTime, long lastUpdateTime,
            Set<String> grantedPermissions, PackageUserState state, int userId) {
            Set<String> grantedPermissions, PackageUserState state, int userId) {
        if (!checkUseInstalledOrHidden(flags, state, p.applicationInfo) || !p.isMatch(flags)) {
        if (!checkUseInstalledOrHidden(flags, state, p.applicationInfo) || !p.isMatch(flags)) {
@@ -809,6 +831,25 @@ public class PackageParser {
                }
                }
            }
            }
        }
        }

        if (apexInfo != null) {
            File apexFile = new File(apexInfo.modulePath);

            pi.applicationInfo.sourceDir = apexFile.getPath();
            pi.applicationInfo.publicSourceDir = apexFile.getPath();
            if (apexInfo.isFactory) {
                pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
            } else {
                pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
            }
            if (apexInfo.isActive) {
                pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
            } else {
                pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
            }
            pi.isApex = true;
        }

        // deprecated method of getting signing certificates
        // deprecated method of getting signing certificates
        if ((flags & PackageManager.GET_SIGNATURES) != 0) {
        if ((flags & PackageManager.GET_SIGNATURES) != 0) {
            if (p.mSigningDetails.hasPastSigningCertificates()) {
            if (p.mSigningDetails.hasPastSigningCertificates()) {
@@ -8461,61 +8502,4 @@ public class PackageParser {
        }
        }
    }
    }


    // TODO(b/129261524): Clean up API
    /**
     * PackageInfo parser specifically for apex files.
     * NOTE: It will collect certificates
     *
     * @param apexInfo
     * @return PackageInfo
     * @throws PackageParserException
     */
    public static PackageInfo generatePackageInfoFromApex(ApexInfo apexInfo, int flags)
            throws PackageParserException {
        PackageParser pp = new PackageParser();
        File apexFile = new File(apexInfo.modulePath);
        final Package p = pp.parsePackage(apexFile, flags, false);
        PackageUserState state = new PackageUserState();
        PackageInfo pi = generatePackageInfo(p, EmptyArray.INT, flags, 0, 0,
                Collections.emptySet(), state);
        pi.applicationInfo.sourceDir = apexFile.getPath();
        pi.applicationInfo.publicSourceDir = apexFile.getPath();
        if (apexInfo.isFactory) {
            pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
        } else {
            pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
        }
        if (apexInfo.isActive) {
            pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
        } else {
            pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
        }
        pi.isApex = true;

        // Collect certificates
        if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) {
            collectCertificates(p, apexFile, false);
            // Keep legacy mechanism for handling signatures. While this is deprecated, it's
            // still part of the public API and needs to be maintained
            if (p.mSigningDetails.hasPastSigningCertificates()) {
                // Package has included signing certificate rotation information.  Return
                // the oldest cert so that programmatic checks keep working even if unaware
                // of key rotation.
                pi.signatures = new Signature[1];
                pi.signatures[0] = p.mSigningDetails.pastSigningCertificates[0];
            } else if (p.mSigningDetails.hasSignatures()) {
                // otherwise keep old behavior
                int numberOfSigs = p.mSigningDetails.signatures.length;
                pi.signatures = new Signature[numberOfSigs];
                System.arraycopy(p.mSigningDetails.signatures, 0, pi.signatures, 0, numberOfSigs);
            }
            if (p.mSigningDetails != SigningDetails.UNKNOWN) {
                // only return a valid SigningInfo if there is signing information to report
                pi.signingInfo = new SigningInfo(p.mSigningDetails);
            } else {
                pi.signingInfo = null;
            }
        }
        return pi;
    }
}
}
+6 −1
Original line number Original line Diff line number Diff line
@@ -520,7 +520,12 @@ public class PackageParserTest {
        apexInfo.modulePath = apexFile.getPath();
        apexInfo.modulePath = apexFile.getPath();
        apexInfo.versionCode = 191000070;
        apexInfo.versionCode = 191000070;
        int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES;
        int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES;
        PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexInfo, flags);

        PackageParser pp = new PackageParser();
        Package p = pp.parsePackage(apexFile, flags, false);
        PackageParser.collectCertificates(p, false);
        PackageInfo pi = PackageParser.generatePackageInfo(p, apexInfo, flags);

        assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName);
        assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName);
        assertTrue(pi.applicationInfo.enabled);
        assertTrue(pi.applicationInfo.enabled);
        assertEquals(28, pi.applicationInfo.targetSdkVersion);
        assertEquals(28, pi.applicationInfo.targetSdkVersion);
+29 −20
Original line number Original line Diff line number Diff line
@@ -282,30 +282,39 @@ abstract class ApexManager {
                        if ((new File(ai.modulePath)).isDirectory()) {
                        if ((new File(ai.modulePath)).isDirectory()) {
                            break;
                            break;
                        }
                        }
                        int flags = PackageManager.GET_META_DATA
                                | PackageManager.GET_SIGNING_CERTIFICATES
                                | PackageManager.GET_SIGNATURES;
                        PackageParser.Package pkg;
                        try {
                        try {
                            final PackageInfo pkg = PackageParser.generatePackageInfoFromApex(
                            File apexFile = new File(ai.modulePath);
                                    ai, PackageManager.GET_META_DATA
                            PackageParser pp = new PackageParser();
                                            | PackageManager.GET_SIGNING_CERTIFICATES);
                            pkg = pp.parsePackage(apexFile, flags, false);
                            mAllPackagesCache.add(pkg);
                            PackageParser.collectCertificates(pkg, false);
                        } catch (PackageParser.PackageParserException pe) {
                            throw new IllegalStateException("Unable to parse: " + ai, pe);
                        }

                        final PackageInfo packageInfo =
                                PackageParser.generatePackageInfo(pkg, ai, flags);
                        mAllPackagesCache.add(packageInfo);
                        if (ai.isActive) {
                        if (ai.isActive) {
                                if (activePackagesSet.contains(pkg.packageName)) {
                            if (activePackagesSet.contains(packageInfo.packageName)) {
                                throw new IllegalStateException(
                                throw new IllegalStateException(
                                        "Two active packages have the same name: "
                                        "Two active packages have the same name: "
                                                    + pkg.packageName);
                                                + packageInfo.packageName);
                            }
                            }
                                activePackagesSet.add(pkg.packageName);
                            activePackagesSet.add(packageInfo.packageName);
                        }
                        }
                        if (ai.isFactory) {
                        if (ai.isFactory) {
                                if (factoryPackagesSet.contains(pkg.packageName)) {
                            if (factoryPackagesSet.contains(packageInfo.packageName)) {
                                throw new IllegalStateException(
                                throw new IllegalStateException(
                                        "Two factory packages have the same name: "
                                        "Two factory packages have the same name: "
                                                    + pkg.packageName);
                                                + packageInfo.packageName);
                            }
                            }
                                factoryPackagesSet.add(pkg.packageName);
                            factoryPackagesSet.add(packageInfo.packageName);
                            }
                        } catch (PackageParser.PackageParserException pe) {
                            throw new IllegalStateException("Unable to parse: " + ai, pe);
                        }
                        }

                    }
                    }
                } catch (RemoteException re) {
                } catch (RemoteException re) {
                    Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString());
                    Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString());
+13 −9
Original line number Original line Diff line number Diff line
@@ -160,25 +160,29 @@ public class StagingManager {
        final ApexInfoList apexInfoList = mApexManager.submitStagedSession(session.sessionId,
        final ApexInfoList apexInfoList = mApexManager.submitStagedSession(session.sessionId,
                childSessionsIds.toArray());
                childSessionsIds.toArray());
        final List<PackageInfo> result = new ArrayList<>();
        final List<PackageInfo> result = new ArrayList<>();
        for (ApexInfo newPackage : apexInfoList.apexInfos) {
        for (ApexInfo apexInfo : apexInfoList.apexInfos) {
            final PackageInfo pkg;
            final PackageInfo packageInfo;
            int flags = PackageManager.GET_META_DATA;
            PackageParser.Package pkg;
            try {
            try {
                pkg = PackageParser.generatePackageInfoFromApex(newPackage,
                File apexFile = new File(apexInfo.modulePath);
                        PackageManager.GET_META_DATA);
                PackageParser pp = new PackageParser();
                pkg = pp.parsePackage(apexFile, flags, false);
            } catch (PackageParserException e) {
            } catch (PackageParserException e) {
                throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
                throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
                        "Failed to parse APEX package " + newPackage.modulePath, e);
                        "Failed to parse APEX package " + apexInfo.modulePath, e);
            }
            }
            final PackageInfo activePackage = mApexManager.getPackageInfo(pkg.packageName,
            packageInfo = PackageParser.generatePackageInfo(pkg, apexInfo, flags);
            final PackageInfo activePackage = mApexManager.getPackageInfo(packageInfo.packageName,
                    ApexManager.MATCH_ACTIVE_PACKAGE);
                    ApexManager.MATCH_ACTIVE_PACKAGE);
            if (activePackage == null) {
            if (activePackage == null) {
                Slog.w(TAG, "Attempting to install new APEX package " + pkg.packageName);
                Slog.w(TAG, "Attempting to install new APEX package " + packageInfo.packageName);
                throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
                throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
                        "It is forbidden to install new APEX packages.");
                        "It is forbidden to install new APEX packages.");
            }
            }
            checkRequiredVersionCode(session, activePackage);
            checkRequiredVersionCode(session, activePackage);
            checkDowngrade(session, activePackage, pkg);
            checkDowngrade(session, activePackage, packageInfo);
            result.add(pkg);
            result.add(packageInfo);
        }
        }
        Slog.d(TAG, "Session " + session.sessionId + " has following APEX packages: ["
        Slog.d(TAG, "Session " + session.sessionId + " has following APEX packages: ["
                + result.stream().map(p -> p.packageName).collect(Collectors.joining(",")) + "]");
                + result.stream().map(p -> p.packageName).collect(Collectors.joining(",")) + "]");