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

Commit 742e7902 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Progress towards staging ASECs.

Move location selection logic into shared PackageHelper location,
and share it between DCS and PackageInstaller.  Fix bugs related to
installed footprint calculation; always count unpacked native libs.

Have PMS do its own threshold checking, since it's fine to stat
devices.  PMS only ever deleted staging ASECs, so move that logic
into installer and nuke unclaimed staging ASECs.  Allocate legacy
ASEC names using PackageInstaller to make sure they don't conflict
with sessions.

Start wiring up session to allocate ASEC and pass through staged
container for installation.

Fix bug to actually delete invalid cluster-style installs.

Bug: 16514385
Change-Id: I325e0c4422fc128398c921ba45fd73ecf05fc2a9
parent 2aaed141
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -8666,14 +8666,14 @@ package android.content.pm {
    field public static final java.lang.String EXTRA_STATUS = "android.content.pm.extra.STATUS";
    field public static final java.lang.String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
    field public static final int STATUS_FAILURE = 1; // 0x1
    field public static final int STATUS_FAILURE_ABORTED = 2; // 0x2
    field public static final int STATUS_FAILURE_BLOCKED = 1; // 0x1
    field public static final int STATUS_FAILURE_CONFLICT = 4; // 0x4
    field public static final int STATUS_FAILURE_INCOMPATIBLE = 6; // 0x6
    field public static final int STATUS_FAILURE_INVALID = 3; // 0x3
    field public static final int STATUS_FAILURE_STORAGE = 5; // 0x5
    field public static final int STATUS_FAILURE_ABORTED = 3; // 0x3
    field public static final int STATUS_FAILURE_BLOCKED = 2; // 0x2
    field public static final int STATUS_FAILURE_CONFLICT = 5; // 0x5
    field public static final int STATUS_FAILURE_INCOMPATIBLE = 7; // 0x7
    field public static final int STATUS_FAILURE_INVALID = 4; // 0x4
    field public static final int STATUS_FAILURE_STORAGE = 6; // 0x6
    field public static final int STATUS_PENDING_USER_ACTION = -1; // 0xffffffff
    field public static final int STATUS_SUCCESS = 0; // 0x0
    field public static final int STATUS_USER_ACTION_REQUIRED = -1; // 0xffffffff
  }
  public static class PackageInstaller.Session implements java.io.Closeable {
@@ -8681,7 +8681,7 @@ package android.content.pm {
    method public void close();
    method public void commit(android.content.IntentSender);
    method public void fsync(java.io.OutputStream) throws java.io.IOException;
    method public java.lang.String[] getNames();
    method public java.lang.String[] getNames() throws java.io.IOException;
    method public java.io.InputStream openRead(java.lang.String) throws java.io.IOException;
    method public java.io.OutputStream openWrite(java.lang.String, long, long) throws java.io.IOException;
    method public void setProgress(float);
+11 −8
Original line number Diff line number Diff line
@@ -129,7 +129,7 @@ public class PackageInstaller {
     *
     * @see Intent#getParcelableExtra(String)
     */
    public static final int STATUS_USER_ACTION_REQUIRED = -1;
    public static final int STATUS_PENDING_USER_ACTION = -1;

    /**
     * The operation succeeded.
@@ -152,7 +152,7 @@ public class PackageInstaller {
     *
     * @see #EXTRA_STATUS_MESSAGE
     */
    public static final int STATUS_FAILURE_BLOCKED = 1;
    public static final int STATUS_FAILURE_BLOCKED = 2;

    /**
     * The operation failed because it was actively aborted. For example, the
@@ -161,7 +161,7 @@ public class PackageInstaller {
     *
     * @see #EXTRA_STATUS_MESSAGE
     */
    public static final int STATUS_FAILURE_ABORTED = 2;
    public static final int STATUS_FAILURE_ABORTED = 3;

    /**
     * The operation failed because one or more of the APKs was invalid. For
@@ -170,7 +170,7 @@ public class PackageInstaller {
     *
     * @see #EXTRA_STATUS_MESSAGE
     */
    public static final int STATUS_FAILURE_INVALID = 3;
    public static final int STATUS_FAILURE_INVALID = 4;

    /**
     * The operation failed because it conflicts (or is inconsistent with) with
@@ -183,7 +183,7 @@ public class PackageInstaller {
     *
     * @see #EXTRA_STATUS_MESSAGE
     */
    public static final int STATUS_FAILURE_CONFLICT = 4;
    public static final int STATUS_FAILURE_CONFLICT = 5;

    /**
     * The operation failed because of storage issues. For example, the device
@@ -192,7 +192,7 @@ public class PackageInstaller {
     *
     * @see #EXTRA_STATUS_MESSAGE
     */
    public static final int STATUS_FAILURE_STORAGE = 5;
    public static final int STATUS_FAILURE_STORAGE = 6;

    /**
     * The operation failed because it is fundamentally incompatible with this
@@ -202,7 +202,7 @@ public class PackageInstaller {
     *
     * @see #EXTRA_STATUS_MESSAGE
     */
    public static final int STATUS_FAILURE_INCOMPATIBLE = 6;
    public static final int STATUS_FAILURE_INCOMPATIBLE = 7;

    private final Context mContext;
    private final PackageManager mPm;
@@ -584,9 +584,12 @@ public class PackageInstaller {
         * This returns all names which have been previously written through
         * {@link #openWrite(String, long, long)} as part of this session.
         */
        public @NonNull String[] getNames() {
        public @NonNull String[] getNames() throws IOException {
            try {
                return mSession.getNames();
            } catch (RuntimeException e) {
                ExceptionUtils.maybeUnwrapIOException(e);
                throw e;
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }
+10 −0
Original line number Diff line number Diff line
@@ -618,6 +618,16 @@ public class StorageManager {
    private static final long DEFAULT_THRESHOLD_MAX_BYTES = 500 * MB_IN_BYTES;
    private static final long DEFAULT_FULL_THRESHOLD_BYTES = MB_IN_BYTES;

    /**
     * Return the number of available bytes until the given path is considered
     * running low on storage.
     *
     * @hide
     */
    public long getStorageBytesUntilLow(File path) {
        return path.getUsableSpace() - getStorageFullBytes(path);
    }

    /**
     * Return the number of available bytes at which the given path is
     * considered running low on storage.
+1 −4
Original line number Diff line number Diff line
@@ -25,10 +25,7 @@ interface IMediaContainerService {
            boolean isExternal, boolean isForwardLocked, String abiOverride);
    int copyPackage(String packagePath, in IParcelFileDescriptorFactory target);

    PackageInfoLite getMinimalPackageInfo(String packagePath, int flags, long threshold,
            String abiOverride);
    boolean checkInternalFreeStorage(String packagePath, boolean isForwardLocked, long threshold);
    boolean checkExternalFreeStorage(String packagePath, boolean isForwardLocked, String abiOverride);
    PackageInfoLite getMinimalPackageInfo(String packagePath, int flags, String abiOverride);
    ObbInfo getObbInfo(String filename);
    long calculateDirectorySize(String directory);
    /** Return file system stats: [0] is total bytes, [1] is available bytes */
+81 −2
Original line number Diff line number Diff line
@@ -16,14 +16,21 @@

package com.android.internal.content;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.os.FileUtils;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.storage.IMountService;
import android.os.storage.StorageManager;
import android.os.storage.StorageResultCode;
import android.util.Log;

import libcore.io.IoUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -33,8 +40,6 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import libcore.io.IoUtils;

/**
 * Constants used internally between the PackageManager
 * and media container service transports.
@@ -298,4 +303,78 @@ public class PackageHelper {
        }
        return false;
    }

    /**
     * Given a requested {@link PackageInfo#installLocation} and calculated
     * install size, pick the actual location to install the app.
     */
    public static int resolveInstallLocation(Context context, int installLocation, long sizeBytes,
            int installFlags) {
        final int prefer;
        final boolean checkBoth;
        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
            prefer = RECOMMEND_INSTALL_INTERNAL;
            checkBoth = false;
        } else if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
            prefer = RECOMMEND_INSTALL_EXTERNAL;
            checkBoth = false;
        } else if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
            prefer = RECOMMEND_INSTALL_INTERNAL;
            checkBoth = false;
        } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
            prefer = RECOMMEND_INSTALL_EXTERNAL;
            checkBoth = true;
        } else if (installLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
            prefer = RECOMMEND_INSTALL_INTERNAL;
            checkBoth = true;
        } else {
            prefer = RECOMMEND_INSTALL_INTERNAL;
            checkBoth = false;
        }

        final boolean emulated = Environment.isExternalStorageEmulated();
        final StorageManager storage = StorageManager.from(context);

        boolean fitsOnInternal = false;
        if (checkBoth || prefer == RECOMMEND_INSTALL_INTERNAL) {
            fitsOnInternal = (sizeBytes
                    <= storage.getStorageBytesUntilLow(Environment.getDataDirectory()));
        }

        boolean fitsOnExternal = false;
        if (!emulated && (checkBoth || prefer == RECOMMEND_INSTALL_EXTERNAL)) {
            fitsOnExternal = (sizeBytes
                    <= storage.getStorageBytesUntilLow(Environment.getExternalStorageDirectory()));
        }

        if (prefer == RECOMMEND_INSTALL_INTERNAL) {
            if (fitsOnInternal) {
                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
            }
        } else if (!emulated && prefer == RECOMMEND_INSTALL_EXTERNAL) {
            if (fitsOnExternal) {
                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
            }
        }

        if (checkBoth) {
            if (fitsOnInternal) {
                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
            } else if (!emulated && fitsOnExternal) {
                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
            }
        }

        /*
         * If they requested to be on the external media by default, return that
         * the media was unavailable. Otherwise, indicate there was insufficient
         * storage space available.
         */
        if (!emulated && (checkBoth || prefer == RECOMMEND_INSTALL_EXTERNAL)
                && !Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            return PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE;
        } else {
            return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
        }
    }
}
Loading