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

Commit 397bfec3 authored by Jakob Schneider's avatar Jakob Schneider Committed by Android (Google) Code Review
Browse files

Merge "Clear archive state when the deletion is not successful." into main

parents 57adba18 82aff709
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -698,7 +698,7 @@ final class InstallPackageHelper {
                    pkgSetting.setUninstallReason(PackageManager.UNINSTALL_REASON_UNKNOWN, userId);
                    pkgSetting.setFirstInstallTime(System.currentTimeMillis(), userId);
                    // Clear any existing archive state.
                    pkgSetting.setArchiveState(null, userId);
                    mPm.mInstallerService.mPackageArchiver.clearArchiveState(packageName, userId);
                    mPm.mSettings.writePackageRestrictionsLPr(userId);
                    mPm.mSettings.writeKernelMappingLPr(pkgSetting);
                    installed = true;
@@ -2281,7 +2281,7 @@ final class InstallPackageHelper {
                                installerPackageName);
                    }
                    // Clear any existing archive state.
                    ps.setArchiveState(null, userId);
                    mPm.mInstallerService.mPackageArchiver.clearArchiveState(pkgName, userId);
                } else if (allUsers != null) {
                    // The caller explicitly specified INSTALL_ALL_USERS flag.
                    // Thus, updating the settings to install the app for all users.
@@ -2305,7 +2305,8 @@ final class InstallPackageHelper {
                                        installerPackageName);
                            }
                            // Clear any existing archive state.
                            ps.setArchiveState(null, currentUserId);
                            mPm.mInstallerService.mPackageArchiver.clearArchiveState(pkgName,
                                    currentUserId);
                        } else {
                            ps.setInstalled(false, currentUserId);
                        }
+48 −12
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ import android.graphics.drawable.LayerDrawable;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
import android.os.IBinder;
import android.os.ParcelableException;
import android.os.Process;
@@ -309,6 +310,26 @@ public class PackageArchiver {
        return false;
    }

    void clearArchiveState(String packageName, int userId) {
        synchronized (mPm.mLock) {
            PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
            if (ps != null) {
                ps.setArchiveState(/* archiveState= */ null, userId);
            }
        }
        mPm.mBackgroundHandler.post(
                () -> {
                    File iconsDir = getIconsDir(packageName, userId);
                    if (!iconsDir.exists()) {
                        return;
                    }
                    // TODO(b/319238030) Move this into installd.
                    if (!FileUtils.deleteContentsAndDir(iconsDir)) {
                        Slog.e(TAG, "Failed to clean up archive files for " + packageName);
                    }
                });
    }

    @Nullable
    private String getCurrentLauncherPackageName(int userId) {
        ComponentName defaultLauncherComponent = mPm.snapshotComputer().getDefaultHomeActivity(
@@ -437,8 +458,8 @@ public class PackageArchiver {
        if (mainActivity.iconBitmap == null) {
            return null;
        }
        File iconsDir = createIconsDir(userId);
        File iconFile = new File(iconsDir, packageName + "-" + index + ".png");
        File iconsDir = createIconsDir(packageName, userId);
        File iconFile = new File(iconsDir, index + ".png");
        try (FileOutputStream out = new FileOutputStream(iconFile)) {
            out.write(mainActivity.iconBitmap);
            out.flush();
@@ -454,14 +475,14 @@ public class PackageArchiver {
            // The app doesn't define an icon. No need to store anything.
            return null;
        }
        File iconsDir = createIconsDir(userId);
        File iconFile = new File(iconsDir, packageName + "-" + index + ".png");
        File iconsDir = createIconsDir(packageName, userId);
        File iconFile = new File(iconsDir, index + ".png");
        Bitmap icon = drawableToBitmap(mainActivity.getIcon(/* density= */ 0), iconSize);
        try (FileOutputStream out = new FileOutputStream(iconFile)) {
            // Note: Quality is ignored for PNGs.
            if (!icon.compress(Bitmap.CompressFormat.PNG, /* quality= */ 100, out)) {
                throw new IOException(TextUtils.formatSimple("Failure to store icon file %s",
                        iconFile.getName()));
                        iconFile.getAbsolutePath()));
            }
            out.flush();
        }
@@ -793,8 +814,20 @@ public class PackageArchiver {
    }

    @VisibleForTesting
    Bitmap decodeIcon(ArchiveActivityInfo archiveActivityInfo) {
        return BitmapFactory.decodeFile(archiveActivityInfo.getIconBitmap().toString());
    @Nullable
    Bitmap decodeIcon(ArchiveActivityInfo activityInfo) {
        Path iconBitmap = activityInfo.getIconBitmap();
        if (iconBitmap == null) {
            return null;
        }
        Bitmap bitmap = BitmapFactory.decodeFile(iconBitmap.toString());
        // TODO(b/278553670) We should throw here after some time. Failing graciously now because
        // we've just changed the place where we store icons.
        if (bitmap == null) {
            Slog.e(TAG, "Archived icon cannot be decoded " + iconBitmap.toAbsolutePath());
            return null;
        }
        return bitmap;
    }

    Bitmap includeCloudOverlay(Bitmap bitmap) {
@@ -1075,8 +1108,9 @@ public class PackageArchiver {
        }
    }

    private static File createIconsDir(@UserIdInt int userId) throws IOException {
        File iconsDir = getIconsDir(userId);
    private static File createIconsDir(String packageName, @UserIdInt int userId)
            throws IOException {
        File iconsDir = getIconsDir(packageName, userId);
        if (!iconsDir.isDirectory()) {
            iconsDir.delete();
            iconsDir.mkdirs();
@@ -1088,8 +1122,10 @@ public class PackageArchiver {
        return iconsDir;
    }

    private static File getIconsDir(int userId) {
        return new File(Environment.getDataSystemCeDirectory(userId), ARCHIVE_ICONS_DIR);
    private static File getIconsDir(String packageName, int userId) {
        return new File(
                new File(Environment.getDataSystemCeDirectory(userId), ARCHIVE_ICONS_DIR),
                packageName);
    }

    private static byte[] bytesFromBitmapFile(Path path) throws IOException {
+26 −3
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.content.pm.PackageInstaller.UNARCHIVAL_ERROR_NO_CONNECTIVI
import static android.content.pm.PackageInstaller.UNARCHIVAL_ERROR_USER_ACTION_NEEDED;
import static android.content.pm.PackageInstaller.UNARCHIVAL_GENERIC_ERROR;
import static android.content.pm.PackageInstaller.UNARCHIVAL_OK;
import static android.content.pm.PackageManager.DELETE_ARCHIVE;
import static android.content.pm.PackageManager.INSTALL_UNARCHIVE_DRAFT;
import static android.os.Process.INVALID_UID;
import static android.os.Process.SYSTEM_UID;
@@ -1405,7 +1406,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements

        final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
                statusReceiver, versionedPackage.getPackageName(),
                canSilentlyInstallPackage, userId);
                canSilentlyInstallPackage, userId, mPackageArchiver, flags);
        final boolean shouldShowConfirmationDialog =
                (flags & PackageManager.DELETE_SHOW_DIALOG) != 0;
        if (!shouldShowConfirmationDialog
@@ -1759,7 +1760,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                        binderUid, unarchiveId));
            }

            session.reportUnarchivalStatus(unarchiveId, status, requiredStorageBytes,
            session.reportUnarchivalStatus(status, unarchiveId, requiredStorageBytes,
                    userActionIntent);
        }
    }
@@ -1828,9 +1829,23 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        private final IntentSender mTarget;
        private final String mPackageName;
        private final Notification mNotification;
        private final int mUserId;

        public PackageDeleteObserverAdapter(Context context, IntentSender target,
        @DeleteFlags
        private final int mFlags;

        @Nullable
        private final PackageArchiver mPackageArchiver;

        PackageDeleteObserverAdapter(Context context, IntentSender target,
                String packageName, boolean showNotification, int userId) {
            this(context, target, packageName, showNotification, userId,
                    /* packageArchiver= */ null, /* flags= */ 0);
        }

        PackageDeleteObserverAdapter(Context context, IntentSender target,
                String packageName, boolean showNotification, int userId,
                PackageArchiver packageArchiver, @DeleteFlags int flags) {
            mContext = context;
            mTarget = target;
            mPackageName = packageName;
@@ -1842,6 +1857,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
            } else {
                mNotification = null;
            }
            mUserId = userId;
            mPackageArchiver = packageArchiver;
            mFlags = flags;
        }

        private String getDeviceOwnerDeletedPackageMsg() {
@@ -1883,6 +1901,11 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                        SystemMessage.NOTE_PACKAGE_STATE,
                        mNotification);
            }
            if (mPackageArchiver != null
                    && PackageManager.DELETE_SUCCEEDED != returnCode
                    && (mFlags & DELETE_ARCHIVE) != 0) {
                mPackageArchiver.clearArchiveState(mPackageName, mUserId);
            }
            if (mTarget == null) {
                return;
            }