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

Commit 99d3b9b8 authored by Xiaogang Cui's avatar Xiaogang Cui Committed by Michael Bestas
Browse files

Storage: Add secondary storage support for app installation

Add secondary external storage APIs for app installation. And
change the logic to allow app to be installed into external
storage.

Change-Id: If2f67af7508d020c1d041bb955e3d55136a34acc
parent fedeb99f
Loading
Loading
Loading
Loading

api/current.txt

100644 → 100755
+3 −0
Original line number Diff line number Diff line
@@ -21651,6 +21651,9 @@ package android.os {
    method public static java.lang.String getExternalStorageState(java.io.File);
    method public static java.io.File getRootDirectory();
    method public static deprecated java.lang.String getStorageState(java.io.File);
    method public static java.io.File getSecondaryStorageDirectory();
    method public static java.lang.String getSecondaryStorageState();
    method public static boolean isNoEmulatedStorageExist();
    method public static boolean isExternalStorageEmulated();
    method public static boolean isExternalStorageEmulated(java.io.File);
    method public static boolean isExternalStorageRemovable();
+44 −0
Original line number Diff line number Diff line
@@ -19,10 +19,12 @@ package android.os;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.os.storage.IMountService;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.text.TextUtils;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;
import com.google.android.collect.Lists;

import java.io.File;
@@ -69,10 +71,33 @@ public class Environment {
    private static UserEnvironment sCurrentUser;
    private static boolean sUserRequired;

    private static final Object sLock = new Object();
    @GuardedBy("sLock")

    private static volatile StorageVolume sNoEmulatedVolume;

    static {
        initForCurrentUser();
    }

    private static StorageVolume getNoEmulatedVolume() {
        if (sNoEmulatedVolume == null) {
            synchronized (sLock) {
                if (sNoEmulatedVolume == null) {
                    try {
                        IMountService mountService = IMountService.Stub.asInterface(ServiceManager
                                .getService("mount"));
                        final StorageVolume[] volumes = mountService.getVolumeList();
                        sNoEmulatedVolume = StorageManager.getNoEmulatedVolume(volumes);
                    } catch (Exception e) {
                        Log.e(TAG, "couldn't talk to MountService", e);
                    }
                }
            }
        }
        return sNoEmulatedVolume;
    }

    /** {@hide} */
    public static void initForCurrentUser() {
        final int userId = UserHandle.myUserId();
@@ -150,6 +175,10 @@ public class Environment {
            return mExternalDirsForApp[0];
        }

        public File getSecondaryStorageDirectory() {
            return mExternalDirsForApp[1];
        }

        @Deprecated
        public File getExternalStoragePublicDirectory(String type) {
            return buildExternalStoragePublicDirs(type)[0];
@@ -396,6 +425,11 @@ public class Environment {
        return sCurrentUser.getExternalDirsForApp()[0];
    }

    public static File getSecondaryStorageDirectory() {
        throwIfUserRequired();
        return sCurrentUser.getExternalDirsForApp()[1];
    }

    /** {@hide} */
    public static File getLegacyExternalStorageDirectory() {
        return new File(System.getenv(ENV_EXTERNAL_STORAGE));
@@ -709,6 +743,11 @@ public class Environment {
        return getExternalStorageState(path);
    }

    public static String getSecondaryStorageState() {
        final File externalDir = sCurrentUser.getExternalDirsForApp()[1];
        return getStorageState(externalDir);
    }

    /**
     * Returns the current state of the storage device that provides the given
     * path.
@@ -746,6 +785,11 @@ public class Environment {
        return isExternalStorageRemovable(externalDir);
    }

    public static boolean isNoEmulatedStorageExist() {
        final StorageVolume volume = getNoEmulatedVolume();
        return (volume != null);
    }

    /**
     * Returns whether the storage device that provides the given path is
     * removable.
+10 −0
Original line number Diff line number Diff line
@@ -615,6 +615,16 @@ public class StorageManager {
        return null;
    }

    /**{@hide} */
    public static StorageVolume getNoEmulatedVolume(StorageVolume[] volumes) {
        for (StorageVolume volume : volumes) {
            if (!volume.isEmulated()) {
                return volume;
            }
        }
        return null;
    }

    private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10;
    private static final long DEFAULT_THRESHOLD_MAX_BYTES = 500 * MB_IN_BYTES;
    private static final long DEFAULT_FULL_THRESHOLD_BYTES = MB_IN_BYTES;
+7 −7
Original line number Diff line number Diff line
@@ -377,7 +377,7 @@ public class PackageHelper {
            checkBoth = false;
        }

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

        boolean fitsOnInternal = false;
@@ -387,9 +387,9 @@ public class PackageHelper {
        }

        boolean fitsOnExternal = false;
        if (!emulated && (checkBoth || prefer == RECOMMEND_INSTALL_EXTERNAL)) {
        if (noemulated && (checkBoth || prefer == RECOMMEND_INSTALL_EXTERNAL)) {
            final File target = new UserEnvironment(UserHandle.USER_OWNER)
                    .getExternalStorageDirectory();
                    .getSecondaryStorageDirectory();
            // External is only an option when size is known
            if (sizeBytes > 0) {
                fitsOnExternal = (sizeBytes <= storage.getStorageBytesUntilLow(target));
@@ -400,7 +400,7 @@ public class PackageHelper {
            if (fitsOnInternal) {
                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
            }
        } else if (!emulated && prefer == RECOMMEND_INSTALL_EXTERNAL) {
        } else if (noemulated && prefer == RECOMMEND_INSTALL_EXTERNAL) {
            if (fitsOnExternal) {
                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
            }
@@ -409,7 +409,7 @@ public class PackageHelper {
        if (checkBoth) {
            if (fitsOnInternal) {
                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
            } else if (!emulated && fitsOnExternal) {
            } else if (noemulated && fitsOnExternal) {
                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
            }
        }
@@ -419,8 +419,8 @@ public class PackageHelper {
         * 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())) {
        if (noemulated && (checkBoth || prefer == RECOMMEND_INSTALL_EXTERNAL)
                && !Environment.MEDIA_MOUNTED.equals(Environment.getSecondaryStorageState())) {
            return PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE;
        } else {
            return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
+13 −15
Original line number Diff line number Diff line
@@ -734,9 +734,8 @@ class MountService extends IMountService.Stub

        Slog.d(TAG, "volume state changed for " + path + " (" + oldState + " -> " + state + ")");

        // Tell PackageManager about changes to primary volume state, but only
        // when not emulated.
        if (volume.isPrimary() && !volume.isEmulated()) {
        // Tell PackageManager about changes, not only to primary volume,
        // to all the non-emulated storage volumes
        if (Environment.MEDIA_UNMOUNTED.equals(state)) {
            mPms.updateExternalMediaStatus(false, false);

@@ -750,7 +749,6 @@ class MountService extends IMountService.Stub
        } else if (Environment.MEDIA_MOUNTED.equals(state)) {
            mPms.updateExternalMediaStatus(true, false);
        }
        }

        synchronized (mListeners) {
            for (int i = mListeners.size() -1; i >= 0; i--) {
Loading