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

Commit 83392792 authored by Daniel Nishi's avatar Daniel Nishi Committed by Android (Google) Code Review
Browse files

Merge "Always use GB as the unit in Storage Settings." into oc-dev

parents 0c58fbd3 63a11c56
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -17,14 +17,15 @@
package com.android.settings.deviceinfo;

import android.content.Context;
import android.content.res.Resources;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
import android.text.format.Formatter;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ProgressBar;

import com.android.settings.R;
import com.android.settings.utils.FileSizeFormatter;

public class StorageItemPreference extends Preference {
    public int userHandle;
@@ -44,9 +45,12 @@ public class StorageItemPreference extends Preference {
    }

    public void setStorageSize(long size, long total) {
        setSummary(size == 0
                ? String.valueOf(0)
                : Formatter.formatFileSize(getContext(), size));
        setSummary(
                FileSizeFormatter.formatFileSize(
                        getContext(),
                        size,
                        getGigabyteSuffix(getContext().getResources()),
                        FileSizeFormatter.GIGABYTE_IN_BYTES));
        if (total == 0) {
            mProgressPercent = 0;
        } else {
@@ -75,4 +79,8 @@ public class StorageItemPreference extends Preference {
        updateProgressBar();
        super.onBindViewHolder(view);
    }

    private static int getGigabyteSuffix(Resources res) {
        return res.getIdentifier("gigabyteShort", "string", "android");
    }
}
+116 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.settings.utils;

import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.text.BidiFormatter;
import android.text.format.Formatter;

/**
 * Utility class to aid in formatting file sizes always with the same unit. This is modified from
 * android.text.format.Formatter to fit this purpose.
 */
public final class FileSizeFormatter {
    public static final long KILOBYTE_IN_BYTES = 1000;
    public static final long MEGABYTE_IN_BYTES = KILOBYTE_IN_BYTES * 1000;
    public static final long GIGABYTE_IN_BYTES = MEGABYTE_IN_BYTES * 1000;

    /**
     * Formats a content size to be in the form of bytes, kilobytes, megabytes, etc.
     *
     * <p>As of O, the prefixes are used in their standard meanings in the SI system, so kB = 1000
     * bytes, MB = 1,000,000 bytes, etc.
     *
     * <p class="note">In {@link android.os.Build.VERSION_CODES#N} and earlier, powers of 1024 are
     * used instead, with KB = 1024 bytes, MB = 1,048,576 bytes, etc.
     *
     * <p>If the context has a right-to-left locale, the returned string is wrapped in bidi
     * formatting characters to make sure it's displayed correctly if inserted inside a
     * right-to-left string. (This is useful in cases where the unit strings, like "MB", are
     * left-to-right, but the locale is right-to-left.)
     *
     * @param context Context to use to load the localized units
     * @param sizeBytes size value to be formatted, in bytes
     * @param suffix String id for the unit suffix.
     * @param mult Amount of bytes in the unit. * @return formatted string with the number
     */
    public static String formatFileSize(
            @Nullable Context context, long sizeBytes, int suffix, long mult) {
        if (context == null) {
            return "";
        }
        final Formatter.BytesResult res =
                formatBytes(context.getResources(), sizeBytes, suffix, mult);
        return BidiFormatter.getInstance()
                .unicodeWrap(context.getString(getFileSizeSuffix(context), res.value, res.units));
    }

    private static int getFileSizeSuffix(Context context) {
        final Resources res = context.getResources();
        return res.getIdentifier("fileSizeSuffix", "string", "android");
    }

    /**
     * A simplified version of the SettingsLib file size formatter. The primary difference is that
     * this version always assumes it is doing a "short file size" and allows for a suffix to be
     * provided.
     *
     * @param res Resources to fetch strings with.
     * @param sizeBytes File size in bytes to format.
     * @param suffix String id for the unit suffix.
     * @param mult Amount of bytes in the unit.
     */
    private static Formatter.BytesResult formatBytes(
            Resources res, long sizeBytes, int suffix, long mult) {
        final boolean isNegative = (sizeBytes < 0);
        float result = isNegative ? -sizeBytes : sizeBytes;
        result = result / mult;
        // Note we calculate the rounded long by ourselves, but still let String.format()
        // compute the rounded value. String.format("%f", 0.1) might not return "0.1" due to
        // floating point errors.
        final int roundFactor;
        final String roundFormat;
        if (mult == 1) {
            roundFactor = 1;
            roundFormat = "%.0f";
        } else if (result < 1) {
            roundFactor = 100;
            roundFormat = "%.2f";
        } else if (result < 10) {
            roundFactor = 10;
            roundFormat = "%.1f";
        } else { // 10 <= result < 100
            roundFactor = 1;
            roundFormat = "%.0f";
        }

        if (isNegative) {
            result = -result;
        }
        final String roundedString = String.format(roundFormat, result);

        // Note this might overflow if abs(result) >= Long.MAX_VALUE / 100, but that's like 80PB so
        // it's okay (for now)...
        final long roundedBytes = (((long) Math.round(result * roundFactor)) * mult / roundFactor);

        final String units = res.getString(suffix);

        return new Formatter.BytesResult(roundedString, units, roundedBytes);
    }
}
+4 −4
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@
 */
package com.android.settings.deviceinfo;

import static com.android.settings.TestUtils.KILOBYTE;
import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES;

import static com.google.common.truth.Truth.assertThat;

@@ -54,8 +54,8 @@ public class StorageItemPreferenceTest {

    @Test
    public void testAfterLoad() {
        mPreference.setStorageSize(KILOBYTE, KILOBYTE * 10);
        assertThat(((String) mPreference.getSummary())).isEqualTo("1.00KB");
        mPreference.setStorageSize(MEGABYTE_IN_BYTES * 10, MEGABYTE_IN_BYTES * 100);
        assertThat(((String) mPreference.getSummary())).isEqualTo("0.01GB");
    }

    @Test
@@ -66,7 +66,7 @@ public class StorageItemPreferenceTest {
                (ProgressBar) holder.itemView.findViewById(android.R.id.progress);

        mPreference.onBindViewHolder(holder);
        mPreference.setStorageSize(KILOBYTE, KILOBYTE * 10);
        mPreference.setStorageSize(MEGABYTE_IN_BYTES, MEGABYTE_IN_BYTES * 10);

        assertThat(progressBar.getProgress()).isEqualTo(10);
    }
+10 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.settings.deviceinfo.storage;

import static com.google.common.truth.Truth.assertThat;
import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES;

import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.verify;
@@ -96,13 +97,13 @@ public class SecondaryUserControllerTest {
    public void controllerUpdatesSummaryOfNewPreference() throws Exception {
        mPrimaryUser.name = TEST_NAME;
        mController.displayPreference(mScreen);
        mController.setSize(10L);
        mController.setSize(MEGABYTE_IN_BYTES * 10);
        final ArgumentCaptor<Preference> argumentCaptor = ArgumentCaptor.forClass(Preference.class);

        verify(mGroup).addPreference(argumentCaptor.capture());

        Preference preference = argumentCaptor.getValue();
        assertThat(preference.getSummary()).isEqualTo("10.00B");
        assertThat(preference.getSummary()).isEqualTo("0.01GB");
    }

    @Test
@@ -162,7 +163,12 @@ public class SecondaryUserControllerTest {
        StorageAsyncLoader.AppsStorageResult userResult =
                new StorageAsyncLoader.AppsStorageResult();
        SparseArray<StorageAsyncLoader.AppsStorageResult> result = new SparseArray<>();
        userResult.externalStats = new StorageStatsSource.ExternalStorageStats(99, 33, 33, 33);
        userResult.externalStats =
                new StorageStatsSource.ExternalStorageStats(
                        MEGABYTE_IN_BYTES * 30,
                        MEGABYTE_IN_BYTES * 10,
                        MEGABYTE_IN_BYTES * 10,
                        MEGABYTE_IN_BYTES * 10);
        result.put(10, userResult);

        mController.handleResult(result);
@@ -170,7 +176,7 @@ public class SecondaryUserControllerTest {
        verify(mGroup).addPreference(argumentCaptor.capture());
        Preference preference = argumentCaptor.getValue();

        assertThat(preference.getSummary()).isEqualTo("99.00B");
        assertThat(preference.getSummary()).isEqualTo("0.03GB");
    }

    @Test
+30 −19
Original line number Diff line number Diff line
@@ -15,9 +15,9 @@
 */
package com.android.settings.deviceinfo.storage;

import static com.android.settings.TestUtils.KILOBYTE;

import static com.google.common.truth.Truth.assertThat;
import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;


import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
@@ -50,9 +51,11 @@ import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.deviceinfo.PrivateVolumeSettings;
import com.android.settings.deviceinfo.StorageItemPreference;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settingslib.applications.StorageStatsSource;
import com.android.settingslib.deviceinfo.StorageVolumeProvider;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -80,6 +83,8 @@ public class StorageItemPreferenceControllerTest {
    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        SettingsShadowResources.overrideResource("android:string/fileSizeSuffix", "%1$s %2$s");
        SettingsShadowResources.overrideResource("android:string/gigabyteShort", "GB");
        mContext = spy(RuntimeEnvironment.application.getApplicationContext());
        FakeFeatureFactory.setupForTest(mContext);
        mFakeFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
@@ -96,6 +101,11 @@ public class StorageItemPreferenceControllerTest {
                mPreference.getLayoutResource(), new LinearLayout(mContext), false);
    }

    @After
    public void tearDown() {
        SettingsShadowResources.reset();
    }

    @Test
    public void testUpdateStateWithInitialState() {
        assertThat(mPreference.getSummary().toString()).isEqualTo(
@@ -243,28 +253,29 @@ public class StorageItemPreferenceControllerTest {
                eq(StorageItemPreferenceController.FILES_KEY))).thenReturn(files);
        mController.displayPreference(screen);

        mController.setUsedSize(KILOBYTE * 200); // There should 87kB attributed.
        mController.setUsedSize(MEGABYTE_IN_BYTES * 970); // There should 870MB attributed.
        StorageAsyncLoader.AppsStorageResult result = new StorageAsyncLoader.AppsStorageResult();
        result.gamesSize = KILOBYTE * 8;
        result.videoAppsSize = KILOBYTE * 16;
        result.musicAppsSize = KILOBYTE * 4;
        result.otherAppsSize = KILOBYTE * 9;
        result.systemSize = KILOBYTE * 10; // This value is ignored and overriden now.
        result.externalStats = new StorageStatsSource.ExternalStorageStats(
                KILOBYTE * 50, // total
                KILOBYTE * 10, // audio
                KILOBYTE * 15, // video
                KILOBYTE * 20); // image
        result.gamesSize = MEGABYTE_IN_BYTES * 80;
        result.videoAppsSize = MEGABYTE_IN_BYTES * 160;
        result.musicAppsSize = MEGABYTE_IN_BYTES * 40;
        result.otherAppsSize = MEGABYTE_IN_BYTES * 90;
        result.systemSize = MEGABYTE_IN_BYTES * 100; // This value is ignored and overridden now.
        result.externalStats =
                new StorageStatsSource.ExternalStorageStats(
                        MEGABYTE_IN_BYTES * 500, // total
                        MEGABYTE_IN_BYTES * 100, // audio
                        MEGABYTE_IN_BYTES * 150, // video
                        MEGABYTE_IN_BYTES * 200); // image

        mController.onLoadFinished(result);

        assertThat(audio.getSummary().toString()).isEqualTo("14.00KB"); // 4KB apps + 10KB files
        assertThat(image.getSummary().toString()).isEqualTo("35.00KB"); // 15KB video + 20KB images
        assertThat(games.getSummary().toString()).isEqualTo("8.00KB");
        assertThat(movies.getSummary().toString()).isEqualTo("16.00KB");
        assertThat(apps.getSummary().toString()).isEqualTo("9.00KB");
        assertThat(system.getSummary().toString()).isEqualTo("113KB");
        assertThat(files.getSummary().toString()).isEqualTo("5.00KB");
        assertThat(audio.getSummary().toString()).isEqualTo("0.14GB");
        assertThat(image.getSummary().toString()).isEqualTo("0.35GB");
        assertThat(games.getSummary().toString()).isEqualTo("0.08GB");
        assertThat(movies.getSummary().toString()).isEqualTo("0.16GB");
        assertThat(apps.getSummary().toString()).isEqualTo("0.09GB");
        assertThat(system.getSummary().toString()).isEqualTo("0.10GB");
        assertThat(files.getSummary().toString()).isEqualTo("0.05GB");
    }

    @Test
Loading