Merge "Always use GB as the unit in Storage Settings." into oc-dev
am: 833927929e
Change-Id: I569b89bcf10fa32f86978c80fb646c0d4503b89e
This commit is contained in:
@@ -17,14 +17,15 @@
|
|||||||
package com.android.settings.deviceinfo;
|
package com.android.settings.deviceinfo;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.PreferenceViewHolder;
|
import android.support.v7.preference.PreferenceViewHolder;
|
||||||
import android.text.format.Formatter;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.utils.FileSizeFormatter;
|
||||||
|
|
||||||
public class StorageItemPreference extends Preference {
|
public class StorageItemPreference extends Preference {
|
||||||
public int userHandle;
|
public int userHandle;
|
||||||
@@ -44,9 +45,12 @@ public class StorageItemPreference extends Preference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setStorageSize(long size, long total) {
|
public void setStorageSize(long size, long total) {
|
||||||
setSummary(size == 0
|
setSummary(
|
||||||
? String.valueOf(0)
|
FileSizeFormatter.formatFileSize(
|
||||||
: Formatter.formatFileSize(getContext(), size));
|
getContext(),
|
||||||
|
size,
|
||||||
|
getGigabyteSuffix(getContext().getResources()),
|
||||||
|
FileSizeFormatter.GIGABYTE_IN_BYTES));
|
||||||
if (total == 0) {
|
if (total == 0) {
|
||||||
mProgressPercent = 0;
|
mProgressPercent = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -75,4 +79,8 @@ public class StorageItemPreference extends Preference {
|
|||||||
updateProgressBar();
|
updateProgressBar();
|
||||||
super.onBindViewHolder(view);
|
super.onBindViewHolder(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int getGigabyteSuffix(Resources res) {
|
||||||
|
return res.getIdentifier("gigabyteShort", "string", "android");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
116
src/com/android/settings/utils/FileSizeFormatter.java
Normal file
116
src/com/android/settings/utils/FileSizeFormatter.java
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.deviceinfo;
|
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;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
@@ -54,8 +54,8 @@ public class StorageItemPreferenceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAfterLoad() {
|
public void testAfterLoad() {
|
||||||
mPreference.setStorageSize(KILOBYTE, KILOBYTE * 10);
|
mPreference.setStorageSize(MEGABYTE_IN_BYTES * 10, MEGABYTE_IN_BYTES * 100);
|
||||||
assertThat(((String) mPreference.getSummary())).isEqualTo("1.00KB");
|
assertThat(((String) mPreference.getSummary())).isEqualTo("0.01GB");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -66,7 +66,7 @@ public class StorageItemPreferenceTest {
|
|||||||
(ProgressBar) holder.itemView.findViewById(android.R.id.progress);
|
(ProgressBar) holder.itemView.findViewById(android.R.id.progress);
|
||||||
|
|
||||||
mPreference.onBindViewHolder(holder);
|
mPreference.onBindViewHolder(holder);
|
||||||
mPreference.setStorageSize(KILOBYTE, KILOBYTE * 10);
|
mPreference.setStorageSize(MEGABYTE_IN_BYTES, MEGABYTE_IN_BYTES * 10);
|
||||||
|
|
||||||
assertThat(progressBar.getProgress()).isEqualTo(10);
|
assertThat(progressBar.getProgress()).isEqualTo(10);
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
package com.android.settings.deviceinfo.storage;
|
package com.android.settings.deviceinfo.storage;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
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.Matchers.anyString;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -96,13 +97,13 @@ public class SecondaryUserControllerTest {
|
|||||||
public void controllerUpdatesSummaryOfNewPreference() throws Exception {
|
public void controllerUpdatesSummaryOfNewPreference() throws Exception {
|
||||||
mPrimaryUser.name = TEST_NAME;
|
mPrimaryUser.name = TEST_NAME;
|
||||||
mController.displayPreference(mScreen);
|
mController.displayPreference(mScreen);
|
||||||
mController.setSize(10L);
|
mController.setSize(MEGABYTE_IN_BYTES * 10);
|
||||||
final ArgumentCaptor<Preference> argumentCaptor = ArgumentCaptor.forClass(Preference.class);
|
final ArgumentCaptor<Preference> argumentCaptor = ArgumentCaptor.forClass(Preference.class);
|
||||||
|
|
||||||
verify(mGroup).addPreference(argumentCaptor.capture());
|
verify(mGroup).addPreference(argumentCaptor.capture());
|
||||||
|
|
||||||
Preference preference = argumentCaptor.getValue();
|
Preference preference = argumentCaptor.getValue();
|
||||||
assertThat(preference.getSummary()).isEqualTo("10.00B");
|
assertThat(preference.getSummary()).isEqualTo("0.01GB");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -162,7 +163,12 @@ public class SecondaryUserControllerTest {
|
|||||||
StorageAsyncLoader.AppsStorageResult userResult =
|
StorageAsyncLoader.AppsStorageResult userResult =
|
||||||
new StorageAsyncLoader.AppsStorageResult();
|
new StorageAsyncLoader.AppsStorageResult();
|
||||||
SparseArray<StorageAsyncLoader.AppsStorageResult> result = new SparseArray<>();
|
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);
|
result.put(10, userResult);
|
||||||
|
|
||||||
mController.handleResult(result);
|
mController.handleResult(result);
|
||||||
@@ -170,7 +176,7 @@ public class SecondaryUserControllerTest {
|
|||||||
verify(mGroup).addPreference(argumentCaptor.capture());
|
verify(mGroup).addPreference(argumentCaptor.capture());
|
||||||
Preference preference = argumentCaptor.getValue();
|
Preference preference = argumentCaptor.getValue();
|
||||||
|
|
||||||
assertThat(preference.getSummary()).isEqualTo("99.00B");
|
assertThat(preference.getSummary()).isEqualTo("0.03GB");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -15,9 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.deviceinfo.storage;
|
package com.android.settings.deviceinfo.storage;
|
||||||
|
|
||||||
import static com.android.settings.TestUtils.KILOBYTE;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
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.any;
|
||||||
import static org.mockito.Matchers.anyString;
|
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.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
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.PrivateVolumeSettings;
|
||||||
import com.android.settings.deviceinfo.StorageItemPreference;
|
import com.android.settings.deviceinfo.StorageItemPreference;
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
|
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||||
import com.android.settingslib.applications.StorageStatsSource;
|
import com.android.settingslib.applications.StorageStatsSource;
|
||||||
import com.android.settingslib.deviceinfo.StorageVolumeProvider;
|
import com.android.settingslib.deviceinfo.StorageVolumeProvider;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -80,6 +83,8 @@ public class StorageItemPreferenceControllerTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
SettingsShadowResources.overrideResource("android:string/fileSizeSuffix", "%1$s %2$s");
|
||||||
|
SettingsShadowResources.overrideResource("android:string/gigabyteShort", "GB");
|
||||||
mContext = spy(RuntimeEnvironment.application.getApplicationContext());
|
mContext = spy(RuntimeEnvironment.application.getApplicationContext());
|
||||||
FakeFeatureFactory.setupForTest(mContext);
|
FakeFeatureFactory.setupForTest(mContext);
|
||||||
mFakeFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
|
mFakeFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
|
||||||
@@ -96,6 +101,11 @@ public class StorageItemPreferenceControllerTest {
|
|||||||
mPreference.getLayoutResource(), new LinearLayout(mContext), false);
|
mPreference.getLayoutResource(), new LinearLayout(mContext), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
SettingsShadowResources.reset();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateStateWithInitialState() {
|
public void testUpdateStateWithInitialState() {
|
||||||
assertThat(mPreference.getSummary().toString()).isEqualTo(
|
assertThat(mPreference.getSummary().toString()).isEqualTo(
|
||||||
@@ -243,28 +253,29 @@ public class StorageItemPreferenceControllerTest {
|
|||||||
eq(StorageItemPreferenceController.FILES_KEY))).thenReturn(files);
|
eq(StorageItemPreferenceController.FILES_KEY))).thenReturn(files);
|
||||||
mController.displayPreference(screen);
|
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();
|
StorageAsyncLoader.AppsStorageResult result = new StorageAsyncLoader.AppsStorageResult();
|
||||||
result.gamesSize = KILOBYTE * 8;
|
result.gamesSize = MEGABYTE_IN_BYTES * 80;
|
||||||
result.videoAppsSize = KILOBYTE * 16;
|
result.videoAppsSize = MEGABYTE_IN_BYTES * 160;
|
||||||
result.musicAppsSize = KILOBYTE * 4;
|
result.musicAppsSize = MEGABYTE_IN_BYTES * 40;
|
||||||
result.otherAppsSize = KILOBYTE * 9;
|
result.otherAppsSize = MEGABYTE_IN_BYTES * 90;
|
||||||
result.systemSize = KILOBYTE * 10; // This value is ignored and overriden now.
|
result.systemSize = MEGABYTE_IN_BYTES * 100; // This value is ignored and overridden now.
|
||||||
result.externalStats = new StorageStatsSource.ExternalStorageStats(
|
result.externalStats =
|
||||||
KILOBYTE * 50, // total
|
new StorageStatsSource.ExternalStorageStats(
|
||||||
KILOBYTE * 10, // audio
|
MEGABYTE_IN_BYTES * 500, // total
|
||||||
KILOBYTE * 15, // video
|
MEGABYTE_IN_BYTES * 100, // audio
|
||||||
KILOBYTE * 20); // image
|
MEGABYTE_IN_BYTES * 150, // video
|
||||||
|
MEGABYTE_IN_BYTES * 200); // image
|
||||||
|
|
||||||
mController.onLoadFinished(result);
|
mController.onLoadFinished(result);
|
||||||
|
|
||||||
assertThat(audio.getSummary().toString()).isEqualTo("14.00KB"); // 4KB apps + 10KB files
|
assertThat(audio.getSummary().toString()).isEqualTo("0.14GB");
|
||||||
assertThat(image.getSummary().toString()).isEqualTo("35.00KB"); // 15KB video + 20KB images
|
assertThat(image.getSummary().toString()).isEqualTo("0.35GB");
|
||||||
assertThat(games.getSummary().toString()).isEqualTo("8.00KB");
|
assertThat(games.getSummary().toString()).isEqualTo("0.08GB");
|
||||||
assertThat(movies.getSummary().toString()).isEqualTo("16.00KB");
|
assertThat(movies.getSummary().toString()).isEqualTo("0.16GB");
|
||||||
assertThat(apps.getSummary().toString()).isEqualTo("9.00KB");
|
assertThat(apps.getSummary().toString()).isEqualTo("0.09GB");
|
||||||
assertThat(system.getSummary().toString()).isEqualTo("113KB");
|
assertThat(system.getSummary().toString()).isEqualTo("0.10GB");
|
||||||
assertThat(files.getSummary().toString()).isEqualTo("5.00KB");
|
assertThat(files.getSummary().toString()).isEqualTo("0.05GB");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
package com.android.settings.deviceinfo.storage;
|
package com.android.settings.deviceinfo.storage;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES;
|
||||||
|
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -108,7 +109,12 @@ public class UserProfileControllerTest {
|
|||||||
SparseArray<StorageAsyncLoader.AppsStorageResult> result = new SparseArray<>();
|
SparseArray<StorageAsyncLoader.AppsStorageResult> result = new SparseArray<>();
|
||||||
StorageAsyncLoader.AppsStorageResult userResult =
|
StorageAsyncLoader.AppsStorageResult userResult =
|
||||||
new StorageAsyncLoader.AppsStorageResult();
|
new StorageAsyncLoader.AppsStorageResult();
|
||||||
userResult.externalStats = new StorageStatsSource.ExternalStorageStats(99, 33, 33, 33);
|
userResult.externalStats =
|
||||||
|
new StorageStatsSource.ExternalStorageStats(
|
||||||
|
99 * MEGABYTE_IN_BYTES,
|
||||||
|
33 * MEGABYTE_IN_BYTES,
|
||||||
|
33 * MEGABYTE_IN_BYTES,
|
||||||
|
33 * MEGABYTE_IN_BYTES);
|
||||||
result.put(10, userResult);
|
result.put(10, userResult);
|
||||||
|
|
||||||
mController.handleResult(result);
|
mController.handleResult(result);
|
||||||
@@ -116,7 +122,7 @@ public class UserProfileControllerTest {
|
|||||||
verify(mScreen).addPreference(argumentCaptor.capture());
|
verify(mScreen).addPreference(argumentCaptor.capture());
|
||||||
Preference preference = argumentCaptor.getValue();
|
Preference preference = argumentCaptor.getValue();
|
||||||
|
|
||||||
assertThat(preference.getSummary()).isEqualTo("99.00B");
|
assertThat(preference.getSummary()).isEqualTo("0.10GB");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -1,5 +1,11 @@
|
|||||||
package com.android.settings.testutils.shadow;
|
package com.android.settings.testutils.shadow;
|
||||||
|
|
||||||
|
import static android.util.TypedValue.TYPE_REFERENCE;
|
||||||
|
|
||||||
|
import static org.robolectric.RuntimeEnvironment.application;
|
||||||
|
import static org.robolectric.Shadows.shadowOf;
|
||||||
|
import static org.robolectric.internal.Shadow.directlyOn;
|
||||||
|
|
||||||
import android.annotation.DimenRes;
|
import android.annotation.DimenRes;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.Resources.NotFoundException;
|
import android.content.res.Resources.NotFoundException;
|
||||||
@@ -12,6 +18,7 @@ import android.support.annotation.ArrayRes;
|
|||||||
import android.support.annotation.ColorRes;
|
import android.support.annotation.ColorRes;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.util.SparseArray;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
@@ -20,21 +27,19 @@ import org.robolectric.RuntimeEnvironment;
|
|||||||
import org.robolectric.annotation.Implementation;
|
import org.robolectric.annotation.Implementation;
|
||||||
import org.robolectric.annotation.Implements;
|
import org.robolectric.annotation.Implements;
|
||||||
import org.robolectric.annotation.RealObject;
|
import org.robolectric.annotation.RealObject;
|
||||||
|
import org.robolectric.internal.Shadow;
|
||||||
import org.robolectric.res.StyleData;
|
import org.robolectric.res.StyleData;
|
||||||
import org.robolectric.res.StyleResolver;
|
import org.robolectric.res.StyleResolver;
|
||||||
import org.robolectric.res.builder.XmlResourceParserImpl;
|
import org.robolectric.res.builder.XmlResourceParserImpl;
|
||||||
import org.robolectric.shadows.ShadowAssetManager;
|
import org.robolectric.shadows.ShadowAssetManager;
|
||||||
import org.robolectric.shadows.ShadowResources;
|
import org.robolectric.shadows.ShadowResources;
|
||||||
import org.robolectric.util.ReflectionHelpers;
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
import org.robolectric.util.ReflectionHelpers.ClassParameter;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static android.util.TypedValue.TYPE_REFERENCE;
|
|
||||||
import static org.robolectric.Shadows.shadowOf;
|
|
||||||
import static org.robolectric.internal.Shadow.directlyOn;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shadow Resources and Theme classes to handle resource references that Robolectric shadows cannot
|
* Shadow Resources and Theme classes to handle resource references that Robolectric shadows cannot
|
||||||
* handle because they are too new or private.
|
* handle because they are too new or private.
|
||||||
@@ -45,6 +50,25 @@ public class SettingsShadowResources extends ShadowResources {
|
|||||||
@RealObject
|
@RealObject
|
||||||
public Resources realResources;
|
public Resources realResources;
|
||||||
|
|
||||||
|
private static SparseArray<Object> sResourceOverrides = new SparseArray<>();
|
||||||
|
|
||||||
|
public static void overrideResource(int id, Object value) {
|
||||||
|
sResourceOverrides.put(id, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void overrideResource(String name, Object value) {
|
||||||
|
final Resources res = application.getResources();
|
||||||
|
final int resId = res.getIdentifier(name, null, null);
|
||||||
|
if (resId == 0) {
|
||||||
|
throw new Resources.NotFoundException("Cannot override \"" + name + "\"");
|
||||||
|
}
|
||||||
|
overrideResource(resId, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void reset() {
|
||||||
|
sResourceOverrides.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Implementation
|
@Implementation
|
||||||
public int getDimensionPixelSize(@DimenRes int id) throws NotFoundException {
|
public int getDimensionPixelSize(@DimenRes int id) throws NotFoundException {
|
||||||
// Handle requests for private dimension resources,
|
// Handle requests for private dimension resources,
|
||||||
@@ -93,6 +117,16 @@ public class SettingsShadowResources extends ShadowResources {
|
|||||||
return directlyOn(realResources, Resources.class).getIntArray(id);
|
return directlyOn(realResources, Resources.class).getIntArray(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Implementation
|
||||||
|
public String getString(int id) {
|
||||||
|
final Object override = sResourceOverrides.get(id);
|
||||||
|
if (override instanceof String) {
|
||||||
|
return (String) override;
|
||||||
|
}
|
||||||
|
return Shadow.directlyOn(
|
||||||
|
realResources, Resources.class, "getString", ClassParameter.from(int.class, id));
|
||||||
|
}
|
||||||
|
|
||||||
@Implements(Theme.class)
|
@Implements(Theme.class)
|
||||||
public static class SettingsShadowTheme extends ShadowTheme {
|
public static class SettingsShadowTheme extends ShadowTheme {
|
||||||
|
|
||||||
|
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* 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 static com.android.settings.utils.FileSizeFormatter.GIGABYTE_IN_BYTES;
|
||||||
|
import static com.android.settings.utils.FileSizeFormatter.MEGABYTE_IN_BYTES;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.filters.SmallTest;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class FileSizeFormatterTest {
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
mContext = InstrumentationRegistry.getTargetContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void formatFileSize_zero() throws Exception {
|
||||||
|
assertThat(
|
||||||
|
FileSizeFormatter.formatFileSize(
|
||||||
|
mContext,
|
||||||
|
0 /* size */,
|
||||||
|
com.android.internal.R.string.gigabyteShort,
|
||||||
|
GIGABYTE_IN_BYTES))
|
||||||
|
.isEqualTo("0.00 GB");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void formatFileSize_smallSize() throws Exception {
|
||||||
|
assertThat(
|
||||||
|
FileSizeFormatter.formatFileSize(
|
||||||
|
mContext,
|
||||||
|
MEGABYTE_IN_BYTES * 11 /* size */,
|
||||||
|
com.android.internal.R.string.gigabyteShort,
|
||||||
|
GIGABYTE_IN_BYTES))
|
||||||
|
.isEqualTo("0.01 GB");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void formatFileSize_lessThanOneSize() throws Exception {
|
||||||
|
assertThat(
|
||||||
|
FileSizeFormatter.formatFileSize(
|
||||||
|
mContext,
|
||||||
|
MEGABYTE_IN_BYTES * 155 /* size */,
|
||||||
|
com.android.internal.R.string.gigabyteShort,
|
||||||
|
GIGABYTE_IN_BYTES))
|
||||||
|
.isEqualTo("0.16 GB");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void formatFileSize_greaterThanOneSize() throws Exception {
|
||||||
|
assertThat(
|
||||||
|
FileSizeFormatter.formatFileSize(
|
||||||
|
mContext,
|
||||||
|
MEGABYTE_IN_BYTES * 1551 /* size */,
|
||||||
|
com.android.internal.R.string.gigabyteShort,
|
||||||
|
GIGABYTE_IN_BYTES))
|
||||||
|
.isEqualTo("1.6 GB");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void formatFileSize_greaterThanTen() throws Exception {
|
||||||
|
// Should round down due to truncation
|
||||||
|
assertThat(
|
||||||
|
FileSizeFormatter.formatFileSize(
|
||||||
|
mContext,
|
||||||
|
GIGABYTE_IN_BYTES * 15 + MEGABYTE_IN_BYTES * 50 /* size */,
|
||||||
|
com.android.internal.R.string.gigabyteShort,
|
||||||
|
GIGABYTE_IN_BYTES))
|
||||||
|
.isEqualTo("15 GB");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void formatFileSize_handlesNegativeFileSizes() throws Exception {
|
||||||
|
assertThat(
|
||||||
|
FileSizeFormatter.formatFileSize(
|
||||||
|
mContext,
|
||||||
|
MEGABYTE_IN_BYTES * -155 /* size */,
|
||||||
|
com.android.internal.R.string.gigabyteShort,
|
||||||
|
GIGABYTE_IN_BYTES))
|
||||||
|
.isEqualTo("-0.16 GB");
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user