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

Commit b4e39f5b authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Prevent apps from uninstalling packages that are not installed by them." into nyc-dev

parents 4e5bbc3e 29283375
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -862,8 +862,12 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
                IntentSender statusReceiver, int userId) {
        final int callingUid = Binder.getCallingUid();
        mPm.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
        boolean allowSilentUninstall = true;
        if ((callingUid != Process.SHELL_UID) && (callingUid != Process.ROOT_UID)) {
            mAppOps.checkPackage(callingUid, callerPackageName);
            final String installerPackageName = mPm.getInstallerPackageName(packageName);
            allowSilentUninstall = installerPackageName != null
                    && installerPackageName.equals(callerPackageName);
        }

        // Check whether the caller is device owner, in which case we do it silently.
@@ -874,8 +878,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub {

        final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
                statusReceiver, packageName, isDeviceOwner, userId);
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES)
                == PackageManager.PERMISSION_GRANTED) {
        if (allowSilentUninstall && mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.DELETE_PACKAGES) == PackageManager.PERMISSION_GRANTED) {
            // Sweet, call straight through!
            mPm.deletePackage(packageName, adapter.getBinder(), userId, flags);
        } else if (isDeviceOwner) {
+4 −1
Original line number Diff line number Diff line
@@ -11754,6 +11754,9 @@ public class PackageManagerService extends IPackageManager.Stub {
            // Okay!
            targetPackageSetting.installerPackageName = installerPackageName;
            if (installerPackageName != null) {
                mSettings.mInstallerPackages.add(installerPackageName);
            }
            scheduleWriteSettingsLocked();
        }
    }
@@ -14895,7 +14898,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     *  This method is an internal method that could be get invoked either
     *  to delete an installed package or to clean up a failed installation.
     *  After deleting an installed package, a broadcast is sent to notify any
     *  listeners that the package has been installed. For cleaning up a failed
     *  listeners that the package has been removed. For cleaning up a failed
     *  installation, the broadcast is not necessary since the package's
     *  installation wouldn't have sent the initial broadcast either
     *  The key steps in deleting a package are
+32 −0
Original line number Diff line number Diff line
@@ -247,6 +247,9 @@ final class Settings {
    /** Map from package name to settings */
    final ArrayMap<String, PackageSetting> mPackages = new ArrayMap<>();

    /** List of packages that installed other packages */
    final ArraySet<String> mInstallerPackages = new ArraySet<>();

    /** Map from package name to appId */
    private final ArrayMap<String, Integer> mKernelMapping = new ArrayMap<>();

@@ -506,6 +509,9 @@ final class Settings {
        PackageSetting p = mPackages.get(pkgName);
        if (p != null) {
            p.setInstallerPackageName(installerPkgName);
            if (installerPkgName != null) {
                mInstallerPackages.add(installerPkgName);
            }
        }
    }

@@ -1062,6 +1068,7 @@ final class Settings {
        final PackageSetting p = mPackages.get(name);
        if (p != null) {
            mPackages.remove(name);
            removeInstallerPackageStatus(name);
            if (p.sharedUser != null) {
                p.sharedUser.removePackage(p);
                if (p.sharedUser.packages.size() == 0) {
@@ -1077,6 +1084,26 @@ final class Settings {
        return -1;
    }

    /**
     * Checks if {@param packageName} is an installer package and if so, clear the installer
     * package name of the packages that are installed by this.
     */
    private void removeInstallerPackageStatus(String packageName) {
        // Check if the package to be removed is an installer package.
        if (!mInstallerPackages.contains(packageName)) {
            return;
        }
        for (int i = 0; i < mPackages.size(); i++) {
            final PackageSetting ps = mPackages.valueAt(i);
            final String installerPackageName = ps.getInstallerPackageName();
            if (installerPackageName != null
                    && installerPackageName.equals(packageName)) {
                ps.setInstallerPackageName(null);
            }
        }
        mInstallerPackages.remove(packageName);
    }

    private void replacePackageLPw(String name, PackageSetting newp) {
        final PackageSetting p = mPackages.get(name);
        if (p != null) {
@@ -2742,6 +2769,7 @@ final class Settings {
        mPendingPackages.clear();
        mPastSignatures.clear();
        mKeySetRefs.clear();
        mInstallerPackages.clear();

        try {
            if (str == null) {
@@ -3706,6 +3734,10 @@ final class Settings {
                packageSetting.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 0, null);
            }

            if (installerPackageName != null) {
                mInstallerPackages.add(installerPackageName);
            }

            final String installStatusStr = parser.getAttributeValue(null, "installStatus");
            if (installStatusStr != null) {
                if (installStatusStr.equalsIgnoreCase("false")) {