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

Commit 642b7c0f authored by Suchi Amalapurapu's avatar Suchi Amalapurapu Committed by Android (Google) Code Review
Browse files

Merge "Include install location preference when installing packages. Changes...

Merge "Include install location preference when installing packages. Changes include Add new remote call in default container service to determine install location. Rename INSTALL_ON_SDCARD Remove recommentAppInstall method Add some additional flags used in remote stubs. Move check for protected apps prior to copy. Unit tests"
parents 24137908 5b993ce7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -600,7 +600,7 @@ public final class Pm {
            } else if (opt.equals("-t")) {
                installFlags |= PackageManager.INSTALL_ALLOW_TEST;
            } else if (opt.equals("-s")) {
                installFlags |= PackageManager.INSTALL_ON_SDCARD;
                installFlags |= PackageManager.INSTALL_EXTERNAL;
            } else {
                System.err.println("Error: Unknown option: " + opt);
                showUsage();
+0 −96
Original line number Diff line number Diff line
@@ -2659,102 +2659,6 @@ class ContextImpl extends Context {
            return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
        }

        // Constants related to app heuristics
        // No-installation limit for internal flash: 10% or less space available
        private static final double LOW_NAND_FLASH_TRESHOLD = 0.1;

        // SD-to-internal app size threshold: currently set to 1 MB
        private static final long INSTALL_ON_SD_THRESHOLD = (1024 * 1024);

        public int recommendAppInstallLocation(Package pkg) {
            // Initial implementation:
            // 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%

            if (pkg == null) {
                return INSTALL_PARSE_FAILED_NOT_APK;
            }

            StatFs internalFlashStats = new StatFs(Environment.getDataDirectory().getPath());
            StatFs sdcardStats = new StatFs(Environment.getExternalStorageDirectory().getPath());

            long totalInternalFlashSize = (long)internalFlashStats.getBlockCount() *
                    (long)internalFlashStats.getBlockSize();
            long availInternalFlashSize = (long)internalFlashStats.getAvailableBlocks() *
                    (long)internalFlashStats.getBlockSize();
            long availSDSize = (long)sdcardStats.getAvailableBlocks() *
                    (long)sdcardStats.getBlockSize();

            double pctNandFree = (double)availInternalFlashSize / (double)totalInternalFlashSize;

            final String archiveFilePath = pkg.mScanPath;
            File apkFile = new File(archiveFilePath);
            long pkgLen = apkFile.length();

            boolean auto = true;
            // To make final copy
            long reqInstallSize = pkgLen;
            // For dex files
            long reqInternalSize = 1 * pkgLen;
            boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD);
            boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalFlashSize);
            boolean fitsOnSd = (reqInstallSize < availSDSize) && intThresholdOk &&
                    (reqInternalSize < availInternalFlashSize);
            boolean fitsOnInt = intThresholdOk && intAvailOk;

            // Consider application flags preferences as well...
            boolean installOnlyOnSd = (pkg.installLocation ==
                    PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
            boolean installOnlyInternal = (pkg.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(mContext.getContentResolver(),
                        Settings.System.SET_INSTALL_LOCATION, 0) != 0;
                if (setInstallLoc) {
                    // Pick user preference
                    int installPreference = Settings.System.getInt(mContext.getContentResolver(),
                            Settings.System.DEFAULT_INSTALL_LOCATION,
                            PackageInfo.INSTALL_LOCATION_AUTO);
                    if (installPreference == 1) {
                        installOnlyInternal = true;
                        auto = false;
                    } else if (installPreference == 2) {
                        installOnlyOnSd = true;
                        auto = false;
                    }
                }
            }
            if (!auto) {
                if (installOnlyOnSd) {
                    return fitsOnSd ? INSTALL_ON_SDCARD : INSTALL_FAILED_INSUFFICIENT_STORAGE;
                } else if (installOnlyInternal){
                    // Check on internal flash
                    return fitsOnInt ? INSTALL_ON_INTERNAL_FLASH : INSTALL_FAILED_INSUFFICIENT_STORAGE;
                }
            }
            // Try to install internally
            if (fitsOnInt) {
                return INSTALL_ON_INTERNAL_FLASH;
            }
            // Try the sdcard now.
            if (fitsOnSd) {
                return INSTALL_ON_SDCARD;
            }
            // Return error code
            return INSTALL_FAILED_INSUFFICIENT_STORAGE;
        }

        private final ContextImpl mContext;
        private final IPackageManager mPM;

+9 −25
Original line number Diff line number Diff line
@@ -258,14 +258,7 @@ public abstract class PackageManager {
     * package has to be installed on the sdcard.
     * @hide
     */
    public static final int INSTALL_ON_SDCARD = 0x00000008;

    /**
     * Convenience flag parameter to indicate that this package has to be installed
     * on internal flash.
     * @hide
     */
    public static final int INSTALL_ON_INTERNAL_FLASH = 0x00000000;
    public static final int INSTALL_EXTERNAL = 0x00000008;

    /**
     * Flag parameter for
@@ -528,6 +521,14 @@ public abstract class PackageManager {
     */
    public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109;

    /**
     * Installation failed return code: this is passed to the {@link IPackageInstallObserver} by
     * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
     * if the system failed to install the package because of system issues.
     * @hide
     */
    public static final int INSTALL_FAILED_INTERNAL_ERROR = -110;

    /**
     * Indicates the state of installation. Used by PackageManager to
     * figure out incomplete installations. Say a package is being installed
@@ -628,23 +629,6 @@ public abstract class PackageManager {
    public static final String ACTION_CLEAN_EXTERNAL_STORAGE
            = "android.content.pm.CLEAN_EXTERNAL_STORAGE";

    /**
     * Determines best place to install an application: either SD or internal FLASH.
     * If applications explicitly set installLocation in their manifest, that
     * preference takes precedence. If not a recommended location is returned
     * based on current available storage on internal flash or sdcard.
     * @param pkgInfo PackageParser.Package of the package that is to be installed.
     * Call utility method to obtain.
     * @return {@link INSTALL_ON_INTERNAL_FLASH} if it is best to install package on internal
     * storage, {@link INSTALL_ON_SDCARD} if it is best to install package on SD card,
     * and {@link INSTALL_FAILED_INSUFFICIENT_STORAGE} if insufficient space to safely install
     * the application. {@link INSTALL_PARSE_FAILED_NOT_APK} Is returned if any input
     * parameter is <code>null</code>.
     * This recommendation does take into account the package's own flags.
     * @hide
     */
    public abstract int recommendAppInstallLocation(PackageParser.Package pkg);

    /**
     * Retrieve overall information about an application package that is
     * installed on the system.
+1 −0
Original line number Diff line number Diff line
@@ -25,4 +25,5 @@ interface IMediaContainerService {
                String key, String resFileName);
    boolean copyResource(in Uri packageURI,
                in ParcelFileDescriptor outStream);
    int getRecommendedInstallLocation(in Uri fileUri);
}
 No newline at end of file
+28 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.content;

/**
 * Constants used internally between the PackageManager
 * and media container service transports.
 */
public class PackageHelper {
    public static final int RECOMMEND_INSTALL_INTERNAL = 1;
    public static final int RECOMMEND_INSTALL_EXTERNAL = 2;
    public static final int RECOMMEND_FAILED_INSUFFICIENT_STORAGE = -1;
    public static final int RECOMMEND_FAILED_INVALID_APK = -2;
}
Loading