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

Commit 225c7b37 authored by Todd Kennedy's avatar Todd Kennedy Committed by android-build-merger
Browse files

Merge "Handle compressed APK enable/disable" into oc-mr1-dev am: 93721c3a

am: 2a339ad5

Change-Id: Icdb58e4075b9eef157826a9cd1fb6e85b2573447
parents 249a4536 2a339ad5
Loading
Loading
Loading
Loading
+206 −75
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
import static android.content.pm.PackageParser.isApkFile;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDWR;
@@ -19771,6 +19773,10 @@ public class PackageManagerService extends IPackageManager.Stub
        // writer
        synchronized (mPackages) {
            // NOTE: The system package always needs to be enabled; even if it's for
            // a compressed stub. If we don't, installing the system package fails
            // during scan [scanning checks the disabled packages]. We will reverse
            // this later, after we've "installed" the stub.
            // Reinstate the old system package
            enableSystemPackageLPw(disabledPs.pkg);
            // Remove any native libraries from the upgraded package.
@@ -19779,23 +19785,38 @@ public class PackageManagerService extends IPackageManager.Stub
        // Install the system package
        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
        try {
            installPackageFromSystemLIF(disabledPs.codePath, false /*isPrivileged*/, allUserHandles,
                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
        } catch (PackageManagerException e) {
            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
                    + e.getMessage());
            return false;
        } finally {
            if (disabledPs.pkg.isStub) {
                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
            }
        }
        return true;
    }
    /**
     * Installs a package that's already on the system partition.
     */
    private PackageParser.Package installPackageFromSystemLIF(@NonNull File codePath,
            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
            @Nullable PermissionsState origPermissionState, boolean writeSettings)
                    throws PackageManagerException {
        int parseFlags = mDefParseFlags
                | PackageParser.PARSE_MUST_BE_APK
                | PackageParser.PARSE_IS_SYSTEM
                | PackageParser.PARSE_IS_SYSTEM_DIR;
        if (locationIsPrivileged(disabledPs.codePath)) {
        if (isPrivileged || locationIsPrivileged(codePath)) {
            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
        }
        final PackageParser.Package newPkg;
        try {
            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
                0 /* currentTime */, null);
        } catch (PackageManagerException e) {
            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
                    + e.getMessage());
            return false;
        }
        final PackageParser.Package newPkg =
                scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/, 0 /*currentTime*/, null);
        try {
            // update shared libraries for the newly re-installed system package
@@ -19813,17 +19834,21 @@ public class PackageManagerService extends IPackageManager.Stub
            // Propagate the permissions state as we do not want to drop on the floor
            // runtime permissions. The update permissions method below will take
            // care of removing obsolete permissions and grant install permissions.
            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
            if (origPermissionState != null) {
                ps.getPermissionsState().copyFrom(origPermissionState);
            }
            updatePermissionsLPw(newPkg.packageName, newPkg,
                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
            final boolean applyUserRestrictions
                    = (allUserHandles != null) && (origUserHandles != null);
            if (applyUserRestrictions) {
                boolean installedStateChanged = false;
                if (DEBUG_REMOVE) {
                    Slog.d(TAG, "Propagating install state across reinstall");
                }
                for (int userId : allUserHandles) {
                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
                    if (DEBUG_REMOVE) {
                        Slog.d(TAG, "    user " + userId + " => " + installed);
                    }
@@ -19846,7 +19871,7 @@ public class PackageManagerService extends IPackageManager.Stub
                mSettings.writeLPr();
            }
        }
        return true;
        return newPkg;
    }
    private boolean deleteInstalledPackageLIF(PackageSetting ps,
@@ -21779,7 +21804,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
            }
        }
        synchronized (mPackages) {
        if (callingUid == Process.SHELL_UID
                && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
            // Shell can only change whole packages between ENABLED and DISABLED_USER states
@@ -21807,13 +21831,119 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
                // Nothing to do
                return;
            }
            // If we're enabling a system stub, there's a little more work to do.
            // Prior to enabling the package, we need to decompress the APK(s) to the
            // data partition and then replace the version on the system partition.
            final PackageParser.Package deletedPkg = pkgSetting.pkg;
            final boolean isSystemStub = deletedPkg.isStub
                    && deletedPkg.isSystemApp();
            if (isSystemStub
                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
                final File codePath = decompressPackage(deletedPkg);
                if (codePath == null) {
                    Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
                    return;
                }
                // TODO remove direct parsing of the package object during internal cleanup
                // of scan package
                // We need to call parse directly here for no other reason than we need
                // the new package in order to disable the old one [we use the information
                // for some internal optimization to optionally create a new package setting
                // object on replace]. However, we can't get the package from the scan
                // because the scan modifies live structures and we need to remove the
                // old [system] package from the system before a scan can be attempted.
                // Once scan is indempotent we can remove this parse and use the package
                // object we scanned, prior to adding it to package settings.
                final PackageParser pp = new PackageParser();
                pp.setSeparateProcesses(mSeparateProcesses);
                pp.setDisplayMetrics(mMetrics);
                pp.setCallback(mPackageParserCallback);
                final PackageParser.Package tmpPkg;
                try {
                    final int parseFlags = mDefParseFlags
                            | PackageParser.PARSE_MUST_BE_APK
                            | PackageParser.PARSE_IS_SYSTEM
                            | PackageParser.PARSE_IS_SYSTEM_DIR;
                    tmpPkg = pp.parsePackage(codePath, parseFlags);
                } catch (PackageParserException e) {
                    Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
                    return;
                }
                synchronized (mInstallLock) {
                    // Disable the stub and remove any package entries
                    removePackageLI(deletedPkg, true);
                    synchronized (mPackages) {
                        disableSystemPackageLPw(deletedPkg, tmpPkg);
                    }
                    final PackageParser.Package newPkg;
                    try (PackageFreezer freezer =
                            freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
                        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
                                | PackageParser.PARSE_ENFORCE_CODE;
                        newPkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
                                0 /*currentTime*/, null /*user*/);
                        prepareAppDataAfterInstallLIF(newPkg);
                        synchronized (mPackages) {
                            try {
                                updateSharedLibrariesLPr(newPkg, null);
                            } catch (PackageManagerException e) {
                                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
                            }
                            updatePermissionsLPw(newPkg.packageName, newPkg,
                                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
                            mSettings.writeLPr();
                        }
                    } catch (PackageManagerException e) {
                        // Whoops! Something went wrong; try to roll back to the stub
                        Slog.w(TAG, "Failed to install compressed system package:"
                                + pkgSetting.name, e);
                        // Remove the failed install
                        removeCodePathLI(codePath);
                        // Install the system package
                        try (PackageFreezer freezer =
                                freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
                            synchronized (mPackages) {
                                // NOTE: The system package always needs to be enabled; even
                                // if it's for a compressed stub. If we don't, installing the
                                // system package fails during scan [scanning checks the disabled
                                // packages]. We will reverse this later, after we've "installed"
                                // the stub.
                                // This leaves us in a fragile state; the stub should never be
                                // enabled, so, cross your fingers and hope nothing goes wrong
                                // until we can disable the package later.
                                enableSystemPackageLPw(deletedPkg);
                            }
                            installPackageFromSystemLIF(new File(deletedPkg.codePath),
                                    false /*isPrivileged*/, null /*allUserHandles*/,
                                    null /*origUserHandles*/, null /*origPermissionsState*/,
                                    true /*writeSettings*/);
                        } catch (PackageManagerException pme) {
                            Slog.w(TAG, "Failed to restore system package:"
                                    + deletedPkg.packageName, pme);
                        } finally {
                            synchronized (mPackages) {
                                mSettings.disableSystemPackageLPw(
                                        deletedPkg.packageName, true /*replaced*/);
                                mSettings.writeLPr();
                            }
                        }
                        return;
                    }
                    clearAppDataLIF(newPkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
                            | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
                    clearAppProfilesLIF(newPkg, UserHandle.USER_ALL);
                    mDexManager.notifyPackageUpdated(newPkg.packageName,
                            newPkg.baseCodePath, newPkg.splitCodePaths);
                }
            }
            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
                // Don't care about who enables an app.
                callingPackage = null;
            }
            pkgSetting.setEnabled(newState, userId, callingPackage);
                // pkgSetting.pkg.mSetEnabled = newState;
        } else {
            // We're dealing with a component level state change
            // First, verify that this is a valid class name.
@@ -21850,6 +21980,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
                return;
            }
        }
        synchronized (mPackages) {
            scheduleWritePackageRestrictionsLocked(userId);
            updateSequenceNumberLP(pkgSetting, new int[] { userId });
            final long callingId = Binder.clearCallingIdentity();