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

Commit bdec6441 authored by alukin's avatar alukin Committed by Aleksandr Lukin
Browse files

Fix StorageStatsService#getTotalBytes

Fixing getTotalBytes by calling a new API in Vold.

1. Returned the original implementation of rounding logic.
Now it only rounds the bytes by increasing the size,
and never by decreasing.
2. Returned the original logic for all the device sizes <= 512GB  to
prevent any potential regressions.
3. For devices with larger capacities now calling vold (one-time call,
then the value is stored in memory) to get the block device size. It's
a very precise number of bytes, so only doing a small rounding (up to
3GB) to try to bring the totalBytes to a nice-looking value, otherwise
just return as is.

Should be tested together with a Settings UI fix: I3dcc9698403612f961cf0de41925dcbcb43e260b

Verified on multiple devices with storage <= 512GB: b/290892417#comment26.
Also verified for 1TB devices: personally and in b/295265657#comment10

Bug: 290892417
Bug: 295358118
Test: verified manually + manually verified calling of new API
Test: atest FileUtilsTest
Test: atest StorageHostTest
Change-Id: I01d72ede6c3ac62198d04829866655ba5a92dc45
(cherry picked from commit be2ec6d9)
parent 017d5586
Loading
Loading
Loading
Loading
+11 −13
Original line number Original line Diff line number Diff line
@@ -1294,32 +1294,30 @@ public final class FileUtils {
     * Round the given size of a storage device to a nice round power-of-two
     * Round the given size of a storage device to a nice round power-of-two
     * value, such as 256MB or 32GB. This avoids showing weird values like
     * value, such as 256MB or 32GB. This avoids showing weird values like
     * "29.5GB" in UI.
     * "29.5GB" in UI.
     *
     * Some storage devices are still using GiB (powers of 1024) over
     * GB (powers of 1000) measurements and this method takes it into account.
     *
     * Round ranges:
     * Round ranges:
     * ...
     * ...
     * [256 GiB + 1; 512 GiB] -> 512 GB
     * (128 GB; 256 GB]   -> 256 GB
     * [512 GiB + 1; 1 TiB]   -> 1 TB
     * (256 GB; 512 GB]   -> 512 GB
     * [1 TiB + 1; 2 TiB]     -> 2 TB
     * (512 GB; 1000 GB]  -> 1000 GB
     * (1000 GB; 2000 GB] -> 2000 GB
     * ...
     * etc
     * etc
     *
     *
     * @hide
     * @hide
     */
     */
    public static long roundStorageSize(long size) {
    public static long roundStorageSize(long size) {
        long val = 1;
        long val = 1;
        long kiloPow = 1;
        long pow = 1;
        long kibiPow = 1;
        while ((val * pow) < size) {
        while ((val * kibiPow) < size) {
            val <<= 1;
            val <<= 1;
            if (val > 512) {
            if (val > 512) {
                val = 1;
                val = 1;
                kibiPow *= 1024;
                pow *= 1000;
                kiloPow *= 1000;
            }
            }
        }
        }
        return val * kiloPow;

        Log.d(TAG, String.format("Rounded bytes from %d to %d", size, val * pow));
        return val * pow;
    }
    }


    private static long toBytes(long value, String unit) {
    private static long toBytes(long value, String unit) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -174,4 +174,5 @@ interface IStorageManager {
    boolean isAppIoBlocked(in String volumeUuid, int uid, int tid, int reason) = 95;
    boolean isAppIoBlocked(in String volumeUuid, int uid, int tid, int reason) = 95;
    void setCloudMediaProvider(in String authority) = 96;
    void setCloudMediaProvider(in String authority) = 96;
    String getCloudMediaProvider() = 97;
    String getCloudMediaProvider() = 97;
    long getInternalStorageBlockDeviceSize() = 98;
}
}
 No newline at end of file
+9 −0
Original line number Original line Diff line number Diff line
@@ -1358,6 +1358,15 @@ public class StorageManager {
                + Environment.getRootDirectory().getTotalSpace());
                + Environment.getRootDirectory().getTotalSpace());
    }
    }


    /** {@hide} */
    public long getInternalStorageBlockDeviceSize() {
        try {
            return mStorageManager.getInternalStorageBlockDeviceSize();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /** {@hide} */
    /** {@hide} */
    public void mkdirs(File file) {
    public void mkdirs(File file) {
        BlockGuard.getVmPolicy().onPathAccess(file.getAbsolutePath());
        BlockGuard.getVmPolicy().onPathAccess(file.getAbsolutePath());
+26 −39
Original line number Original line Diff line number Diff line
@@ -505,45 +505,32 @@ public class FileUtilsTest {


    @Test
    @Test
    public void testRoundStorageSize() throws Exception {
    public void testRoundStorageSize() throws Exception {
        final long GB1 = DataUnit.GIGABYTES.toBytes(1);
        final long M256 = DataUnit.MEGABYTES.toBytes(256);
        final long GiB1 = DataUnit.GIBIBYTES.toBytes(1);
        final long M512 = DataUnit.MEGABYTES.toBytes(512);
        final long GB2 = DataUnit.GIGABYTES.toBytes(2);
        final long G1 = DataUnit.GIGABYTES.toBytes(1);
        final long GiB2 = DataUnit.GIBIBYTES.toBytes(2);
        final long G2 = DataUnit.GIGABYTES.toBytes(2);
        final long GiB128 = DataUnit.GIBIBYTES.toBytes(128);
        final long G32 = DataUnit.GIGABYTES.toBytes(32);
        final long GB256 = DataUnit.GIGABYTES.toBytes(256);
        final long G64 = DataUnit.GIGABYTES.toBytes(64);
        final long GiB256 = DataUnit.GIBIBYTES.toBytes(256);
        final long G512 = DataUnit.GIGABYTES.toBytes(512);
        final long GB512 = DataUnit.GIGABYTES.toBytes(512);
        final long G1000 = DataUnit.TERABYTES.toBytes(1);
        final long GiB512 = DataUnit.GIBIBYTES.toBytes(512);
        final long G2000 = DataUnit.TERABYTES.toBytes(2);
        final long TB1 = DataUnit.TERABYTES.toBytes(1);

        final long TiB1 = DataUnit.TEBIBYTES.toBytes(1);
        assertEquals(M256, roundStorageSize(M256 - 1));
        final long TB2 = DataUnit.TERABYTES.toBytes(2);
        assertEquals(M256, roundStorageSize(M256));
        final long TiB2 = DataUnit.TEBIBYTES.toBytes(2);
        assertEquals(M512, roundStorageSize(M256 + 1));
        final long TB4 = DataUnit.TERABYTES.toBytes(4);
        assertEquals(M512, roundStorageSize(M512 - 1));
        final long TiB4 = DataUnit.TEBIBYTES.toBytes(4);
        assertEquals(M512, roundStorageSize(M512));
        final long TB8 = DataUnit.TERABYTES.toBytes(8);
        assertEquals(G1, roundStorageSize(M512 + 1));
        final long TiB8 = DataUnit.TEBIBYTES.toBytes(8);
        assertEquals(G1, roundStorageSize(G1));

        assertEquals(G2, roundStorageSize(G1 + 1));
        assertEquals(GB1, roundStorageSize(GB1 - 1));

        assertEquals(GB1, roundStorageSize(GB1));
        assertEquals(G32, roundStorageSize(G32 - 1));
        assertEquals(GB1, roundStorageSize(GB1 + 1));
        assertEquals(G32, roundStorageSize(G32));
        assertEquals(GB1, roundStorageSize(GiB1 - 1));
        assertEquals(G64, roundStorageSize(G32 + 1));
        assertEquals(GB1, roundStorageSize(GiB1));

        assertEquals(GB2, roundStorageSize(GiB1 + 1));
        assertEquals(G512, roundStorageSize(G512 - 1));
        assertEquals(GB2, roundStorageSize(GiB2));
        assertEquals(G1000, roundStorageSize(G512 + 1));

        assertEquals(G2000, roundStorageSize(G1000 + 1));
        assertEquals(GB256, roundStorageSize(GiB128 + 1));
        assertEquals(GB256, roundStorageSize(GiB256));
        assertEquals(GB512, roundStorageSize(GiB256 + 1));
        assertEquals(GB512, roundStorageSize(GiB512));
        assertEquals(TB1, roundStorageSize(GiB512 + 1));
        assertEquals(TB1, roundStorageSize(TiB1));
        assertEquals(TB2, roundStorageSize(TiB1 + 1));
        assertEquals(TB2, roundStorageSize(TiB2));
        assertEquals(TB4, roundStorageSize(TiB2 + 1));
        assertEquals(TB4, roundStorageSize(TiB4));
        assertEquals(TB8, roundStorageSize(TiB4 + 1));
        assertEquals(TB8, roundStorageSize(TiB8));
        assertEquals(TB1, roundStorageSize(1013077688320L)); // b/268571529
    }
    }


    @Test
    @Test
+12 −1
Original line number Original line Diff line number Diff line
@@ -73,8 +73,8 @@ import android.content.pm.ProviderInfo;
import android.content.pm.UserInfo;
import android.content.pm.UserInfo;
import android.content.res.ObbInfo;
import android.content.res.ObbInfo;
import android.database.ContentObserver;
import android.database.ContentObserver;
import android.media.MediaCodecList;
import android.media.MediaCodecInfo;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.media.MediaFormat;
import android.media.MediaFormat;
import android.net.Uri;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.BatteryManager;
@@ -219,6 +219,8 @@ class StorageManagerService extends IStorageManager.Stub
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private final Set<Integer> mCeStoragePreparedUsers = new ArraySet<>();
    private final Set<Integer> mCeStoragePreparedUsers = new ArraySet<>();


    private volatile long mInternalStorageSize = 0;

    public static class Lifecycle extends SystemService {
    public static class Lifecycle extends SystemService {
        private StorageManagerService mStorageManagerService;
        private StorageManagerService mStorageManagerService;


@@ -3479,6 +3481,15 @@ class StorageManagerService extends IStorageManager.Stub
        return authority;
        return authority;
    }
    }


    @Override
    public long getInternalStorageBlockDeviceSize() throws RemoteException {
        if (mInternalStorageSize == 0) {
            mInternalStorageSize = mVold.getStorageSize();
        }

        return mInternalStorageSize;
    }

    /**
    /**
     * Enforces that the caller is the {@link ExternalStorageService}
     * Enforces that the caller is the {@link ExternalStorageService}
     *
     *
Loading