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

Commit f4d4d89a authored by John Wu's avatar John Wu Committed by Android (Google) Code Review
Browse files

Merge "Support system app update leaving shared UID then getting uninstalled"

parents c67f8fa5 d8597aa9
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -458,10 +458,8 @@ final class DeletePackageHelper {
        mAppDataHelper.destroyAppProfilesLIF(pkg);

        final SharedUserSetting sus = ps.getSharedUser();
        List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages() : null;
        if (sharedUserPkgs == null) {
            sharedUserPkgs = Collections.emptyList();
        }
        final List<AndroidPackage> sharedUserPkgs =
                sus != null ? sus.getPackages() : Collections.emptyList();
        final int[] userIds = (userId == UserHandle.USER_ALL) ? mUserManagerInternal.getUserIds()
                : new int[] {userId};
        for (int nextUserId : userIds) {
+44 −50
Original line number Diff line number Diff line
@@ -220,8 +220,7 @@ final class RemovePackageHelper {
            outInfo.mInstallerPackageName = deletedPs.getInstallSource().installerPackageName;
            outInfo.mIsStaticSharedLib = deletedPkg != null
                    && deletedPkg.getStaticSharedLibName() != null;
            outInfo.populateUsers(
                    deletedPs == null ? null : deletedPs.queryInstalledUsers(
            outInfo.populateUsers(deletedPs.queryInstalledUsers(
                    mUserManagerInternal.getUserIds(), true), deletedPs);
        }

@@ -249,7 +248,6 @@ final class RemovePackageHelper {

        // writer
        boolean installedStateChanged = false;
        if (deletedPs != null) {
        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
            final SparseBooleanArray changedUsers = new SparseBooleanArray();
            synchronized (mPm.mLock) {
@@ -265,11 +263,8 @@ final class RemovePackageHelper {
                    // If we don't have a disabled system package to reinstall, the package is
                    // really gone and its permission state should be removed.
                    final SharedUserSetting sus = deletedPs.getSharedUser();
                        List<AndroidPackage> sharedUserPkgs = sus != null ? sus.getPackages()
                                : null;
                        if (sharedUserPkgs == null) {
                            sharedUserPkgs = Collections.emptyList();
                        }
                    List<AndroidPackage> sharedUserPkgs =
                            sus != null ? sus.getPackages() : Collections.emptyList();
                    mPermissionManager.onPackageUninstalled(packageName, deletedPs.getAppId(),
                            deletedPs.getPkg(), sharedUserPkgs, UserHandle.USER_ALL);
                }
@@ -303,7 +298,6 @@ final class RemovePackageHelper {
                }
            }
        }
        }
        synchronized (mPm.mLock) {
            // can downgrade to reader
            if (writeSettings) {
+36 −29
Original line number Diff line number Diff line
@@ -802,7 +802,9 @@ public final class Settings implements Watchable, Snappable {
                disabled = p;
            }
            mDisabledSysPackages.put(name, disabled);

            if (disabled.getSharedUser() != null) {
                disabled.getSharedUser().mDisabledPackages.add(disabled);
            }
            return true;
        }
        return false;
@@ -814,6 +816,9 @@ public final class Settings implements Watchable, Snappable {
            Log.w(PackageManagerService.TAG, "Package " + name + " is not disabled");
            return null;
        }
        if (p.getSharedUser() != null) {
            p.getSharedUser().mDisabledPackages.remove(p);
        }
        p.getPkgState().setUpdatedSystemApp(false);
        PackageSetting ret = addPackageLPw(name, p.getRealName(), p.getPath(),
                p.getLegacyNativeLibraryPath(), p.getPrimaryCpuAbi(),
@@ -833,7 +838,11 @@ public final class Settings implements Watchable, Snappable {
    }

    void removeDisabledSystemPackageLPw(String name) {
        mDisabledSysPackages.remove(name);
        final PackageSetting p = mDisabledSysPackages.remove(name);
        if (p != null && p.getSharedUser() != null) {
            p.getSharedUser().mDisabledPackages.remove(p);
            checkAndPruneSharedUserLPw(p.getSharedUser(), false);
        }
    }

    PackageSetting addPackageLPw(String name, String realName, File codePath,
@@ -883,27 +892,24 @@ public final class Settings implements Watchable, Snappable {
    }

    void pruneSharedUsersLPw() {
        ArrayList<String> removeStage = new ArrayList<String>();
        List<String> removeKeys = new ArrayList<>();
        List<SharedUserSetting> removeValues = new ArrayList<>();
        for (Map.Entry<String, SharedUserSetting> entry : mSharedUsers.entrySet()) {
            final SharedUserSetting sus = entry.getValue();
            if (sus == null) {
                removeStage.add(entry.getKey());
                removeKeys.add(entry.getKey());
                continue;
            }
            // remove packages that are no longer installed
            for (Iterator<PackageSetting> iter = sus.packages.iterator(); iter.hasNext();) {
                PackageSetting ps = iter.next();
                if (mPackages.get(ps.getPackageName()) == null) {
                    iter.remove();
                }
            sus.packages.removeIf(ps -> mPackages.get(ps.getPackageName()) == null);
            sus.mDisabledPackages.removeIf(
                    ps -> mDisabledSysPackages.get(ps.getPackageName()) == null);
            if (sus.packages.isEmpty() && sus.mDisabledPackages.isEmpty()) {
                removeValues.add(sus);
            }
            if (sus.packages.size() == 0) {
                removeStage.add(entry.getKey());
            }
        }
        for (int i = 0; i < removeStage.size(); i++) {
            mSharedUsers.remove(removeStage.get(i));
        }
        removeKeys.forEach(mSharedUsers::remove);
        removeValues.forEach(sus -> checkAndPruneSharedUserLPw(sus, true));
    }

    /**
@@ -1233,18 +1239,20 @@ public final class Settings implements Watchable, Snappable {
        }
    }

    private void checkAndPruneSharedUserLPw(SharedUserSetting s, boolean skipCheck) {
        if (skipCheck || (s.packages.isEmpty() && s.mDisabledPackages.isEmpty())) {
            mSharedUsers.remove(s.name);
            removeAppIdLPw(s.userId);
        }
    }

    int removePackageLPw(String name) {
        final PackageSetting p = mPackages.get(name);
        final PackageSetting p = mPackages.remove(name);
        if (p != null) {
            mPackages.remove(name);
            removeInstallerPackageStatus(name);
            if (p.getSharedUser() != null) {
                p.getSharedUser().removePackage(p);
                if (p.getSharedUser().packages.size() == 0) {
                    mSharedUsers.remove(p.getSharedUser().name);
                    removeAppIdLPw(p.getSharedUser().userId);
                    return p.getSharedUser().userId;
                }
                checkAndPruneSharedUserLPw(p.getSharedUser(), false);
            } else {
                removeAppIdLPw(p.getAppId());
                return p.getAppId();
@@ -3052,17 +3060,16 @@ public final class Settings implements Watchable, Snappable {
         * Make sure all the updated system packages have their shared users
         * associated with them.
         */
        final Iterator<PackageSetting> disabledIt = mDisabledSysPackages.values().iterator();
        while (disabledIt.hasNext()) {
            final PackageSetting disabledPs = disabledIt.next();
        for (PackageSetting disabledPs : mDisabledSysPackages.values()) {
            final Object id = getSettingLPr(disabledPs.getAppId());
            if (id != null && id instanceof SharedUserSetting) {
            if (id instanceof SharedUserSetting) {
                disabledPs.setSharedUser((SharedUserSetting) id);
                disabledPs.getSharedUser().mDisabledPackages.add(disabledPs);
            }
        }

        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
                + mSharedUsers.size() + " shared uids\n");
        mReadMessages.append("Read completed successfully: ").append(mPackages.size())
                .append(" packages, ").append(mSharedUsers.size()).append(" shared uids\n");

        writeKernelMappingLPr();

+17 −6
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package com.android.server.pm;

import android.annotation.Nullable;
import android.annotation.NonNull;
import android.content.pm.ApplicationInfo;
import android.content.pm.parsing.component.ParsedProcess;
import android.service.pm.PackageServiceDumpProto;
@@ -31,6 +31,7 @@ import com.android.server.utils.SnapshotCache;
import libcore.util.EmptyArray;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@@ -52,6 +53,11 @@ public final class SharedUserSetting extends SettingBase {

    final ArraySet<PackageSetting> packages;

    // It is possible for a system app to leave shared user ID by an update.
    // We need to keep track of the shadowed PackageSettings so that it is possible to uninstall
    // the update and revert the system app back into the original shared user ID.
    final ArraySet<PackageSetting> mDisabledPackages;

    final PackageSignatures signatures = new PackageSignatures();
    Boolean signaturesChanged;

@@ -77,6 +83,7 @@ public final class SharedUserSetting extends SettingBase {
        name = _name;
        seInfoTargetSdkVersion = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
        packages = new ArraySet<>();
        mDisabledPackages = new ArraySet<>();
        processes = new ArrayMap<>();
        mSnapshot = makeCache();
    }
@@ -87,13 +94,14 @@ public final class SharedUserSetting extends SettingBase {
        name = orig.name;
        uidFlags = orig.uidFlags;
        uidPrivateFlags = orig.uidPrivateFlags;
        packages = new ArraySet(orig.packages);
        packages = new ArraySet<>(orig.packages);
        mDisabledPackages = new ArraySet<>(orig.mDisabledPackages);
        // A SigningDetails seems to consist solely of final attributes, so
        // it is safe to copy the reference.
        signatures.mSigningDetails = orig.signatures.mSigningDetails;
        signaturesChanged = orig.signaturesChanged;
        processes = new ArrayMap(orig.processes);
        mSnapshot = new SnapshotCache.Sealed();
        processes = new ArrayMap<>(orig.processes);
        mSnapshot = new SnapshotCache.Sealed<>();
    }

    /**
@@ -174,9 +182,12 @@ public final class SharedUserSetting extends SettingBase {
        }
    }

    public @Nullable List<AndroidPackage> getPackages() {
    /**
     * @return the list of packages that uses this shared UID
     */
    public @NonNull List<AndroidPackage> getPackages() {
        if (packages == null || packages.size() == 0) {
            return null;
            return Collections.emptyList();
        }
        final ArrayList<AndroidPackage> pkgList = new ArrayList<>(packages.size());
        for (PackageSetting ps : packages) {