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

Commit 14b6abda authored by Suchi Amalapurapu's avatar Suchi Amalapurapu
Browse files

Add new install flag to install on internal flash only

Change default install location policy for new flag.
New error code for media unavailable.

Change-Id: I5a5d0828b067692b2b94a15a2bcc7534f796c1a2
parent d246ca81
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -602,6 +602,9 @@ public final class Pm {
            } else if (opt.equals("-s")) {
                // Override if -s option is specified.
                installFlags |= PackageManager.INSTALL_EXTERNAL;
            } else if (opt.equals("-f")) {
                // Override if -s option is specified.
                installFlags |= PackageManager.INSTALL_INTERNAL;
            } else {
                System.err.println("Error: Unknown option: " + opt);
                showUsage();
@@ -861,7 +864,7 @@ public final class Pm {
        System.err.println("       pm list instrumentation [-f] [TARGET-PACKAGE]");
        System.err.println("       pm list features");
        System.err.println("       pm path PACKAGE");
        System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] PATH");
        System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH");
        System.err.println("       pm uninstall [-k] PACKAGE");
        System.err.println("       pm mountsd [-m true/false]");
        System.err.println("       pm enable PACKAGE_OR_COMPONENT");
@@ -895,6 +898,7 @@ public final class Pm {
        System.err.println("  -t: allow test .apks to be installed.");
        System.err.println("  -i: specify the installer package name.");
        System.err.println("  -s: install package on sdcard.");
        System.err.println("  -f: install package on internal flash.");
        System.err.println("");
        System.err.println("The uninstall command removes a package from the system. Options:");
        System.err.println("  -k: keep the data and cache directories around.");
+7 −0
Original line number Diff line number Diff line
@@ -260,6 +260,13 @@ public abstract class PackageManager {
     */
    public static final int INSTALL_EXTERNAL = 0x00000008;

    /**
    * Flag parameter for {@link #installPackage} to indicate that this
    * package has to be installed on the sdcard.
    * @hide
    */
   public static final int INSTALL_INTERNAL = 0x00000010;

    /**
     * Flag parameter for
     * {@link #setComponentEnabledSetting(android.content.ComponentName, int, int)} to indicate
+1 −1
Original line number Diff line number Diff line
@@ -26,6 +26,6 @@ interface IMediaContainerService {
                String key, String resFileName);
    boolean copyResource(in Uri packageURI,
                in ParcelFileDescriptor outStream);
    PackageInfoLite getMinimalPackageInfo(in Uri fileUri);
    PackageInfoLite getMinimalPackageInfo(in Uri fileUri, int flags);
    boolean checkFreeStorage(boolean external, in Uri fileUri);
}
 No newline at end of file
+89 −62
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ public class DefaultContainerService extends IntentService {
         * @return Returns PackageInfoLite object containing
         * the package info and recommended app location.
         */
        public PackageInfoLite getMinimalPackageInfo(final Uri fileUri) {
        public PackageInfoLite getMinimalPackageInfo(final Uri fileUri, int flags) {
            PackageInfoLite ret = new PackageInfoLite();
            if (fileUri == null) {
                Log.i(TAG, "Invalid package uri " + fileUri);
@@ -136,7 +136,7 @@ public class DefaultContainerService extends IntentService {
                return ret;
            }
            ret.packageName = pkg.packageName;
            ret.recommendedInstallLocation = recommendAppInstallLocation(pkg.installLocation, archiveFilePath);
            ret.recommendedInstallLocation = recommendAppInstallLocation(pkg.installLocation, archiveFilePath, flags);
            return ret;
        }

@@ -305,8 +305,65 @@ public class DefaultContainerService extends IntentService {
    private static final int ERR_LOC = -1;

    private int recommendAppInstallLocation(int installLocation,
            String archiveFilePath) {
        // Initial implementation:
            String archiveFilePath, int flags) {
        boolean checkInt = false;
        boolean checkExt = false;
        boolean checkBoth = false;
        check_inner : {
            // Check flags.
            if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
                // Check for forward locked app
                checkInt = true;
                break check_inner;
            } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
                // Explicit flag to install internally.
                // Check internal storage and return
                checkInt = true;
                break check_inner;
            } else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
                // Explicit flag to install externally.
                // Check external storage and return
                checkExt = true;
                break check_inner;
            }
            // Check for manifest option
            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
                checkInt = true;
                break check_inner;
            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
                checkExt = true;
                checkBoth = true;
                break check_inner;
            } else if (installLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
                checkInt = true;
                checkBoth = true;
                break check_inner;
            }
            // Check if user option is enabled
            boolean setInstallLoc = Settings.System.getInt(getApplicationContext()
                    .getContentResolver(),
                    Settings.System.SET_INSTALL_LOCATION, 0) != 0;
            if (setInstallLoc) {
                // Pick user preference
                int installPreference = Settings.System.getInt(getApplicationContext()
                        .getContentResolver(),
                        Settings.System.DEFAULT_INSTALL_LOCATION,
                        PackageHelper.APP_INSTALL_AUTO);
                if (installPreference == PackageHelper.APP_INSTALL_INTERNAL) {
                    checkInt = true;
                    checkBoth = true;
                    break check_inner;
                } else if (installPreference == PackageHelper.APP_INSTALL_EXTERNAL) {
                    checkExt = true;
                    checkBoth = true;
                    break check_inner;
                }
            }
            // Fall back to default policy if nothing else is specified.
            checkInt = true;
            checkBoth = true;
        }

        // Package size = code size + cache size + data size
        // If code size > 1 MB, install on SD card.
        // Else install on internal NAND flash, unless space on NAND is less than 10%
@@ -331,76 +388,46 @@ public class DefaultContainerService extends IntentService {
        File apkFile = new File(archiveFilePath);
        long pkgLen = apkFile.length();
        
        boolean auto = true;
        // To make final copy
        long reqInstallSize = pkgLen;
        // For dex files. Just ignore and fail when extracting. Max limit of 2Gig for now.
        long reqInternalSize = 0;
        boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD);
        boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalSize);
        boolean fitsOnSd = mediaAvailable && (reqInstallSize < availSDSize)
                 && intThresholdOk &&
                (reqInternalSize < availInternalSize);
        boolean fitsOnInt = intThresholdOk && intAvailOk;

        // Consider application flags preferences as well...
        boolean installOnlyOnSd = (installLocation ==
                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
        boolean installOnlyInternal = (installLocation ==
                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
        if (installOnlyInternal) {
            // If set explicitly in manifest,
            // let that override everything else
            auto = false;
        } else if (installOnlyOnSd){
            // Check if this can be accommodated on the sdcard
            if (fitsOnSd) {
                auto = false;
            }
        } else {
            // Check if user option is enabled
            boolean setInstallLoc = Settings.System.getInt(getApplicationContext()
                    .getContentResolver(),
                    Settings.System.SET_INSTALL_LOCATION, 0) != 0;
            if (setInstallLoc) {
                // Pick user preference
                int installPreference = Settings.System.getInt(getApplicationContext()
                        .getContentResolver(),
                        Settings.System.DEFAULT_INSTALL_LOCATION,
                        PackageHelper.APP_INSTALL_AUTO);
                if (installPreference == PackageHelper.APP_INSTALL_INTERNAL) {
                    installOnlyInternal = true;
                    auto = false;
                } else if (installPreference == PackageHelper.APP_INSTALL_EXTERNAL) {
                    installOnlyOnSd = true;
                    auto = false;
        boolean fitsOnSd = false;
        if (mediaAvailable && (reqInstallSize < availSDSize)) {
            // If we do not have an internal size requirement
            // don't do a threshold check.
            if (reqInternalSize == 0) {
                fitsOnSd = true;
            } else if ((reqInternalSize < availInternalSize) && intThresholdOk) {
                fitsOnSd = true;
            }
        }
        boolean fitsOnInt = intThresholdOk && intAvailOk;
        if (checkInt) {
            // Check for internal memory availability
            if (fitsOnInt) {
                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
            }
        if (!auto) {
            if (installOnlyOnSd) {
        } else if (checkExt) {
            if (fitsOnSd) {
                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
            }
                if (!mediaAvailable) {
                    return PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE;
        }
                return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
            } else if (installOnlyInternal){
                // Check on internal flash
                return fitsOnInt ?  PackageHelper.RECOMMEND_INSTALL_INTERNAL :
                    PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
            }
        }
        // Try to install internally
        if (checkBoth) {
            // Check for internal first
            if (fitsOnInt) {
                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
            }
        // Try the sdcard now.
            // Check for external next
            if (fitsOnSd) {
                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
            }
        // Return error code
        }
        if (checkExt || checkBoth && !mediaAvailable) {
            return PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE;
        }
        return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
    }

+18 −8
Original line number Diff line number Diff line
@@ -595,11 +595,14 @@ class PackageManagerService extends IPackageManager.Stub {

    static boolean installOnSd(int flags) {
        if (((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) ||
                ((flags & PackageManager.INSTALL_EXTERNAL) == 0)) {
                ((flags & PackageManager.INSTALL_INTERNAL) != 0)) {
            return false;
        }
        if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
            return true;
        }
        return false;
    }

    static boolean isFwdLocked(int flags) {
        if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
@@ -4452,8 +4455,8 @@ class PackageManagerService extends IPackageManager.Stub {
                res.uid = -1;
                res.pkg = null;
                res.removedInfo = new PackageRemovedInfo();
                args.doPreInstall(res.returnCode);
                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
                    args.doPreInstall(res.returnCode);
                    synchronized (mInstallLock) {
                        installPackageLI(args, true, res);
                    }
@@ -4623,13 +4626,18 @@ class PackageManagerService extends IPackageManager.Stub {
            int ret = PackageManager.INSTALL_SUCCEEDED;
            boolean fwdLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
            boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
            // Dont need to invoke getInstallLocation for forward locked apps.
            if (fwdLocked && onSd) {
            boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0;
            if (onInt && onSd) {
                // Check if both bits are set.
                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
            } else if (fwdLocked && onSd) {
                // Check for forward locked apps
                Slog.w(TAG, "Cannot install fwd locked apps on sdcard");
                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
            } else {
                // Remote call to find out default install location
                PackageInfoLite pkgLite = mContainerService.getMinimalPackageInfo(packageURI);
                PackageInfoLite pkgLite = mContainerService.getMinimalPackageInfo(packageURI, flags);
                int loc = pkgLite.recommendedInstallLocation;
                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION){
                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
@@ -4644,14 +4652,16 @@ class PackageManagerService extends IPackageManager.Stub {
                } else {
                    // Override with defaults if needed.
                    loc = installLocationPolicy(pkgLite, flags);
                    if (!onSd && !onInt) {
                        // Override install location with flags
                    if ((flags & PackageManager.INSTALL_EXTERNAL) == 0){
                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
                            // Set the flag to install on external media.
                            flags |= PackageManager.INSTALL_EXTERNAL;
                            flags &= ~PackageManager.INSTALL_INTERNAL;
                        } else {
                            // Make sure the flag for installing on external
                            // media is unset
                            flags |= PackageManager.INSTALL_INTERNAL;
                            flags &= ~PackageManager.INSTALL_EXTERNAL;
                        }
                    }
Loading