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

Commit bd3af28f authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Candidate volumes for packages, fix symlink."

parents dae67ef3 e2d45be4
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.util.ArrayMap;
import android.util.Log;
import android.view.Display;
@@ -1426,6 +1428,61 @@ final class ApplicationPackageManager extends PackageManager {
        }
    }

    @Override
    public @NonNull VolumeInfo getApplicationCurrentVolume(ApplicationInfo app) {
        final StorageManager storage = mContext.getSystemService(StorageManager.class);
        if (app.isInternal()) {
            return Preconditions.checkNotNull(
                    storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL));
        } else if (app.isExternalAsec()) {
            final List<VolumeInfo> vols = storage.getVolumes();
            for (VolumeInfo vol : vols) {
                if ((vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.isPrimary()) {
                    return vol;
                }
            }
            throw new IllegalStateException("Failed to find primary public volume");
        } else {
            return Preconditions.checkNotNull(storage.findVolumeByUuid(app.volumeUuid));
        }
    }

    @Override
    public @NonNull List<VolumeInfo> getApplicationCandidateVolumes(ApplicationInfo app) {
        final StorageManager storage = mContext.getSystemService(StorageManager.class);
        final List<VolumeInfo> vols = storage.getVolumes();
        final List<VolumeInfo> candidates = new ArrayList<>();
        for (VolumeInfo vol : vols) {
            if (isCandidateVolume(app, vol)) {
                candidates.add(vol);
            }
        }
        return candidates;
    }

    private static boolean isCandidateVolume(ApplicationInfo app, VolumeInfo vol) {
        // Private internal is always an option
        if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
            return true;
        }

        // System apps and apps demanding internal storage can't be moved
        // anywhere else
        if (app.isSystemApp()
                || app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
            return false;
        }

        // Moving into an ASEC on public primary is only an option when app is
        // internal, or already in ASEC
        if ((vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.isPrimary()) {
            return app.isInternal() || app.isExternalAsec();
        }

        // Otherwise we can move to any private volume
        return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
    }

    @Override
    public String getInstallerPackageName(String packageName) {
        try {
+12 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Printer;

import com.android.internal.util.ArrayUtils;
@@ -937,6 +938,17 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
        return (flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
    }

    /** @hide */
    public boolean isInternal() {
        return (flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0;
    }

    /** @hide */
    public boolean isExternalAsec() {
        return TextUtils.isEmpty(volumeUuid)
                && (flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
    }

    /**
     * @hide
     */
+7 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.CheckResult;
import android.annotation.DrawableRes;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.StringRes;
@@ -4162,6 +4163,12 @@ public abstract class PackageManager {
    public abstract void movePackageAndData(String packageName, String volumeUuid,
            IPackageMoveObserver observer);

    /** {@hide} */
    public abstract @Nullable VolumeInfo getApplicationCurrentVolume(ApplicationInfo app);

    /** {@hide} */
    public abstract @NonNull List<VolumeInfo> getApplicationCandidateVolumes(ApplicationInfo app);

    /**
     * Returns the device identity that verifiers can use to associate their scheme to a particular
     * device. This should not be used by anything other than a package verifier.
+15 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;

import java.io.CharArrayWriter;
import java.util.Objects;

/**
 * Information about a physical disk which may contain one or more
@@ -118,6 +119,20 @@ public class DiskInfo implements Parcelable {
        }
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof DiskInfo) {
            return Objects.equals(id, ((DiskInfo) o).id);
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return id.hashCode();
    }

    public static final Creator<DiskInfo> CREATOR = new Creator<DiskInfo>() {
        @Override
        public DiskInfo createFromParcel(Parcel in) {
+36 −0
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ import com.android.internal.util.Preconditions;

import java.io.CharArrayWriter;
import java.io.File;
import java.util.Comparator;
import java.util.Objects;

/**
 * Information about a storage volume that may be mounted. A volume may be a
@@ -77,6 +79,22 @@ public class VolumeInfo implements Parcelable {
    private static SparseArray<String> sStateToEnvironment = new SparseArray<>();
    private static ArrayMap<String, String> sEnvironmentToBroadcast = new ArrayMap<>();

    private static final Comparator<VolumeInfo>
            sDescriptionComparator = new Comparator<VolumeInfo>() {
        @Override
        public int compare(VolumeInfo lhs, VolumeInfo rhs) {
            if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(lhs.getId())) {
                return -1;
            } else if (lhs.getDescription() == null) {
                return 1;
            } else if (rhs.getDescription() == null) {
                return -1;
            } else {
                return lhs.getDescription().compareTo(rhs.getDescription());
            }
        }
    };

    static {
        sStateToEnvironment.put(VolumeInfo.STATE_UNMOUNTED, Environment.MEDIA_UNMOUNTED);
        sStateToEnvironment.put(VolumeInfo.STATE_MOUNTING, Environment.MEDIA_CHECKING);
@@ -150,6 +168,10 @@ public class VolumeInfo implements Parcelable {
        return getBroadcastForEnvironment(getEnvironmentForState(state));
    }

    public static @NonNull Comparator<VolumeInfo> getDescriptionComparator() {
        return sDescriptionComparator;
    }

    public @NonNull String getId() {
        return id;
    }
@@ -344,6 +366,20 @@ public class VolumeInfo implements Parcelable {
        }
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof VolumeInfo) {
            return Objects.equals(id, ((VolumeInfo) o).id);
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return id.hashCode();
    }

    public static final Creator<VolumeInfo> CREATOR = new Creator<VolumeInfo>() {
        @Override
        public VolumeInfo createFromParcel(Parcel in) {
Loading