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

Commit b521feae authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Update file size formatting.

Per UX, default strings should have space between value and units
resulting in "12.3 GB".  Add a formatting variant that returns the
various components for callers who want to build their own strings.

For now there is only one mounted emulated volume at a time, and
it's always the primary storage, so give it the default rootId to
keep old Uris working.

Change-Id: Ifcc72a91a6b397ee65dc92642153286186eb64ac
parent 0463cad7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -53,6 +53,8 @@ public class TrafficStats {
    public static final long GB_IN_BYTES = MB_IN_BYTES * 1024;
    /** @hide */
    public static final long TB_IN_BYTES = GB_IN_BYTES * 1024;
    /** @hide */
    public static final long PB_IN_BYTES = TB_IN_BYTES * 1024;

    /**
     * Special UID value used when collecting {@link NetworkStatsHistory} for
+48 −16
Original line number Diff line number Diff line
@@ -17,7 +17,9 @@
package android.text.format;

import android.content.Context;
import android.content.res.Resources;
import android.net.NetworkUtils;
import android.net.TrafficStats;

/**
 * Utility class to aid in formatting common values that are not covered
@@ -25,63 +27,88 @@ import android.net.NetworkUtils;
 */
public final class Formatter {

    /** {@hide} */
    public static final int FLAG_SHORTER = 1 << 0;
    /** {@hide} */
    public static final int FLAG_CALCULATE_ROUNDED = 1 << 1;

    /** {@hide} */
    public static class BytesResult {
        public final String value;
        public final String units;
        public final long roundedBytes;

        public BytesResult(String value, String units, long roundedBytes) {
            this.value = value;
            this.units = units;
            this.roundedBytes = roundedBytes;
        }
    }

    /**
     * Formats a content size to be in the form of bytes, kilobytes, megabytes, etc
     *
     * @param context Context to use to load the localized units
     * @param number size value to be formatted
     * @param sizeBytes size value to be formatted, in bytes
     * @return formatted string with the number
     */
    public static String formatFileSize(Context context, long number) {
        return formatFileSize(context, number, false);
    public static String formatFileSize(Context context, long sizeBytes) {
        final BytesResult res = formatBytes(context.getResources(), sizeBytes, 0);
        return context.getString(com.android.internal.R.string.fileSizeSuffix,
                res.value, res.units);
    }

    /**
     * Like {@link #formatFileSize}, but trying to generate shorter numbers
     * (showing fewer digits of precision).
     */
    public static String formatShortFileSize(Context context, long number) {
        return formatFileSize(context, number, true);
    public static String formatShortFileSize(Context context, long sizeBytes) {
        final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SHORTER);
        return context.getString(com.android.internal.R.string.fileSizeSuffix,
                res.value, res.units);
    }

    private static String formatFileSize(Context context, long number, boolean shorter) {
        if (context == null) {
            return "";
        }

        float result = number;
    /** {@hide} */
    public static BytesResult formatBytes(Resources res, long sizeBytes, int flags) {
        float result = sizeBytes;
        int suffix = com.android.internal.R.string.byteShort;
        long mult = 1;
        if (result > 900) {
            suffix = com.android.internal.R.string.kilobyteShort;
            mult = TrafficStats.KB_IN_BYTES;
            result = result / 1024;
        }
        if (result > 900) {
            suffix = com.android.internal.R.string.megabyteShort;
            mult = TrafficStats.MB_IN_BYTES;
            result = result / 1024;
        }
        if (result > 900) {
            suffix = com.android.internal.R.string.gigabyteShort;
            mult = TrafficStats.GB_IN_BYTES;
            result = result / 1024;
        }
        if (result > 900) {
            suffix = com.android.internal.R.string.terabyteShort;
            mult = TrafficStats.TB_IN_BYTES;
            result = result / 1024;
        }
        if (result > 900) {
            suffix = com.android.internal.R.string.petabyteShort;
            mult = TrafficStats.PB_IN_BYTES;
            result = result / 1024;
        }
        String value;
        if (result < 1) {
            value = String.format("%.2f", result);
        } else if (result < 10) {
            if (shorter) {
            if ((flags & FLAG_SHORTER) != 0) {
                value = String.format("%.1f", result);
            } else {
                value = String.format("%.2f", result);
            }
        } else if (result < 100) {
            if (shorter) {
            if ((flags & FLAG_SHORTER) != 0) {
                value = String.format("%.0f", result);
            } else {
                value = String.format("%.2f", result);
@@ -89,9 +116,14 @@ public final class Formatter {
        } else {
            value = String.format("%.0f", result);
        }
        return context.getResources().
            getString(com.android.internal.R.string.fileSizeSuffix,
                      value, context.getString(suffix));
        final String units = res.getString(suffix);
        final long roundedBytes;
        if ((flags & FLAG_CALCULATE_ROUNDED) != 0) {
            roundedBytes = (long) (Double.parseDouble(value) * mult);
        } else {
            roundedBytes = 0;
        }
        return new BytesResult(value, units, roundedBytes);
    }

    /**
+12 −9
Original line number Diff line number Diff line
@@ -120,13 +120,20 @@ public class ExternalStorageProvider extends DocumentsProvider {
            if (!volume.isMountedReadable()) continue;

            final String rootId;
            if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) {
            final String title;
            if (volume.getType() == VolumeInfo.TYPE_EMULATED) {
                // We currently only support a single emulated volume mounted at
                // a time, and it's always considered the primary
                rootId = ROOT_ID_PRIMARY_EMULATED;
            } else if (volume.getType() == VolumeInfo.TYPE_EMULATED) {
                if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) {
                    title = getContext().getString(R.string.root_internal_storage);
                } else {
                    final VolumeInfo privateVol = mStorageManager.findPrivateForEmulated(volume);
                rootId = privateVol.getFsUuid();
                    title = mStorageManager.getBestVolumeDescription(privateVol);
                }
            } else if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
                rootId = volume.getFsUuid();
                title = mStorageManager.getBestVolumeDescription(volume);
            } else {
                // Unsupported volume; ignore
                continue;
@@ -148,11 +155,7 @@ public class ExternalStorageProvider extends DocumentsProvider {
                root.rootId = rootId;
                root.flags = Root.FLAG_SUPPORTS_CREATE | Root.FLAG_LOCAL_ONLY | Root.FLAG_ADVANCED
                        | Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_IS_CHILD;
                if (ROOT_ID_PRIMARY_EMULATED.equals(rootId)) {
                    root.title = getContext().getString(R.string.root_internal_storage);
                } else {
                    root.title = mStorageManager.getBestVolumeDescription(volume);
                }
                root.title = title;
                if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
                    root.flags |= Root.FLAG_HAS_SETTINGS;
                }
+1 −1

File changed.

Contains only whitespace changes.