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

Commit 23a2a0da authored by Todd Kennedy's avatar Todd Kennedy
Browse files

Always populate the ApplicationInfo object

While scanning system apps, we abort package/application info setup
if an app on /system is not a higher version than an upgrade on /data.
Instead, we need to still fully populate these objects because they
can be retrievd using the MATCH_FACTORY_ONLY flag.

Change-Id: I0262b46f446eace60ce94f1428f3fb15d785a89c
Fixes: 62980149
Test: Manual
Test: Create a sample application that dumps the contents of an ApplicationInfo object for a given package
Test: Install the sample application on the /system partition and "upgrade" the sample application so it's also on the /data partition
Test: Create a secondary user and disable the sample application
Test: Reboot the device
Test: Run the sample application as the primary user and see that the ApplicationInfo object is correctly populated
(cherry picked from commit c606627e)
parent a083c8f8
Loading
Loading
Loading
Loading
+40 −34
Original line number Diff line number Diff line
@@ -8938,9 +8938,12 @@ public class PackageManagerService extends IPackageManager.Stub
            }
        }
        boolean updatedPkgBetter = false;
        final boolean isUpdatedPkg = updatedPkg != null;
        final boolean isUpdatedSystemPkg = isUpdatedPkg
                && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0;
        boolean isUpdatedPkgBetter = false;
        // First check if this is a system package that may involve an update
        if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
        if (isUpdatedSystemPkg) {
            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
            // it needs to drop FLAG_PRIVILEGED.
            if (locationIsPrivileged(scanFile)) {
@@ -8984,10 +8987,6 @@ public class PackageManagerService extends IPackageManager.Stub
                            updatedChildPkg.versionCode = pkg.mVersionCode;
                        }
                    }
                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
                            + scanFile + " ignored: updated version " + ps.versionCode
                            + " better than this " + pkg.mVersionCode);
                } else {
                    // The current app on the system partition is better than
                    // what we have updated to on the data partition; switch
@@ -9014,12 +9013,44 @@ public class PackageManagerService extends IPackageManager.Stub
                    synchronized (mPackages) {
                        mSettings.enableSystemPackageLPw(ps.name);
                    }
                    updatedPkgBetter = true;
                    isUpdatedPkgBetter = true;
                }
            }
        }
        if (updatedPkg != null) {
        String resourcePath = null;
        String baseResourcePath = null;
        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !isUpdatedPkgBetter) {
            if (ps != null && ps.resourcePathString != null) {
                resourcePath = ps.resourcePathString;
                baseResourcePath = ps.resourcePathString;
            } else {
                // Should not happen at all. Just log an error.
                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
            }
        } else {
            resourcePath = pkg.codePath;
            baseResourcePath = pkg.baseCodePath;
        }
        // Set application objects path explicitly.
        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
        pkg.setApplicationInfoCodePath(pkg.codePath);
        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
        pkg.setApplicationInfoResourcePath(resourcePath);
        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
        // throw an exception if we have an update to a system application, but, it's not more
        // recent than the package we've already scanned
        if (isUpdatedSystemPkg && !isUpdatedPkgBetter) {
            throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
                    + scanFile + " ignored: updated version " + ps.versionCode
                    + " better than this " + pkg.mVersionCode);
        }
        if (isUpdatedPkg) {
            // An updated system app will not have the PARSE_IS_SYSTEM flag set
            // initially
            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
@@ -9039,7 +9070,7 @@ public class PackageManagerService extends IPackageManager.Stub
         * same name installed earlier.
         */
        boolean shouldHideSystemApp = false;
        if (updatedPkg == null && ps != null
        if (!isUpdatedPkg && ps != null
                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
            /*
             * Check to make sure the signatures match first. If they don't,
@@ -9094,31 +9125,6 @@ public class PackageManagerService extends IPackageManager.Stub
            }
        }
        // TODO: extend to support forward-locked splits
        String resourcePath = null;
        String baseResourcePath = null;
        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
            if (ps != null && ps.resourcePathString != null) {
                resourcePath = ps.resourcePathString;
                baseResourcePath = ps.resourcePathString;
            } else {
                // Should not happen at all. Just log an error.
                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
            }
        } else {
            resourcePath = pkg.codePath;
            baseResourcePath = pkg.baseCodePath;
        }
        // Set application objects path explicitly.
        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
        pkg.setApplicationInfoCodePath(pkg.codePath);
        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
        pkg.setApplicationInfoResourcePath(resourcePath);
        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
        final int userId = ((user == null) ? 0 : user.getIdentifier());
        if (ps != null && ps.getInstantApp(userId)) {
            scanFlags |= SCAN_AS_INSTANT_APP;