Merge "Consistent "low storage" behavior." into oc-dev
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 4974f78..13b3d0b 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -131,7 +131,7 @@
}
}
- mPreferenceController.onLoadFinished(mAppsResult.get(UserHandle.myUserId()));
+ mPreferenceController.onLoadFinished(mAppsResult, UserHandle.myUserId());
updateSecondaryUserControllers(mSecondaryUsers, mAppsResult);
// setLoading always causes a flicker, so let's avoid doing it.
diff --git a/src/com/android/settings/deviceinfo/StorageProfileFragment.java b/src/com/android/settings/deviceinfo/StorageProfileFragment.java
index 7e2d941..dee6793 100644
--- a/src/com/android/settings/deviceinfo/StorageProfileFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageProfileFragment.java
@@ -120,7 +120,8 @@
@Override
public void onLoadFinished(Loader<SparseArray<AppsStorageResult>> loader,
SparseArray<AppsStorageResult> result) {
- mPreferenceController.onLoadFinished(scrubAppsFromResult(result.get(mUserId)));
+ scrubAppsFromResult(result.get(mUserId));
+ mPreferenceController.onLoadFinished(result, mUserId);
}
@Override
diff --git a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
index 8652804..74474b3 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
@@ -22,8 +22,8 @@
import android.content.Context;
import android.content.pm.ApplicationInfo;
-import android.content.pm.UserInfo;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArray;
@@ -87,45 +87,43 @@
stats = mStatsManager.getStatsForPackage(mUuid, app.packageName, myUser);
} catch (NameNotFoundException | IOException e) {
// This may happen if the package was removed during our calculation.
- Log.w("App unexpectedly not found", e);
+ Log.w(TAG, "App unexpectedly not found", e);
continue;
}
- long attributedAppSizeInBytes = stats.getDataBytes();
- // This matches how the package manager calculates sizes -- by zeroing out code sizes of
- // system apps which are not updated. My initial tests suggest that this results in the
- // original code size being counted for updated system apps when they shouldn't, but
- // I am not sure how to avoid this problem without specifically going in to find that
- // code size.
- if (!app.isSystemApp() || app.isUpdatedSystemApp()) {
- attributedAppSizeInBytes += stats.getCodeBytes();
- } else {
- result.systemSize += stats.getCodeBytes();
+ long blamedSize = stats.getDataBytes() - stats.getCacheBytes();
+
+ // Only count app code against the current user; we don't want
+ // double-counting on multi-user devices.
+ if (userId == UserHandle.myUserId()) {
+ blamedSize += stats.getCodeBytes();
}
+
switch (app.category) {
case CATEGORY_GAME:
- result.gamesSize += attributedAppSizeInBytes;
+ result.gamesSize += blamedSize;
break;
case CATEGORY_AUDIO:
- result.musicAppsSize += attributedAppSizeInBytes;
+ result.musicAppsSize += blamedSize;
break;
case CATEGORY_VIDEO:
- result.videoAppsSize += attributedAppSizeInBytes;
+ result.videoAppsSize += blamedSize;
break;
default:
// The deprecated game flag does not set the category.
if ((app.flags & ApplicationInfo.FLAG_IS_GAME) != 0) {
- result.gamesSize += attributedAppSizeInBytes;
+ result.gamesSize += blamedSize;
break;
}
- result.otherAppsSize += attributedAppSizeInBytes;
+ result.otherAppsSize += blamedSize;
break;
}
}
Log.d(TAG, "Loading external stats");
try {
- result.externalStats = mStatsManager.getExternalStorageStats(mUuid, UserHandle.of(userId));
+ result.externalStats = mStatsManager.getExternalStorageStats(mUuid,
+ UserHandle.of(userId));
} catch (IOException e) {
Log.w(TAG, e);
}
@@ -142,7 +140,6 @@
public long musicAppsSize;
public long videoAppsSize;
public long otherAppsSize;
- public long systemSize;
public StorageStatsSource.ExternalStorageStats externalStats;
}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index f8df375..cebd114 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -23,6 +23,7 @@
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
+import android.net.TrafficStats;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.storage.VolumeInfo;
@@ -30,6 +31,7 @@
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.util.Log;
+import android.util.SparseArray;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
@@ -237,7 +239,10 @@
setFilesPreferenceVisibility();
}
- public void onLoadFinished(StorageAsyncLoader.AppsStorageResult data) {
+ public void onLoadFinished(SparseArray<StorageAsyncLoader.AppsStorageResult> result,
+ int userId) {
+ final StorageAsyncLoader.AppsStorageResult data = result.get(userId);
+
// TODO(b/35927909): Figure out how to split out apps which are only installed for work
// profiles in order to attribute those app's code bytes only to that profile.
mPhotoPreference.setStorageSize(
@@ -248,23 +253,30 @@
mMoviesPreference.setStorageSize(data.videoAppsSize, mTotalSize);
mAppPreference.setStorageSize(data.otherAppsSize, mTotalSize);
- long unattributedExternalBytes =
+ long otherExternalBytes =
data.externalStats.totalBytes
- data.externalStats.audioBytes
- data.externalStats.videoBytes
- - data.externalStats.imageBytes;
- mFilePreference.setStorageSize(unattributedExternalBytes, mTotalSize);
+ - data.externalStats.imageBytes
+ - data.externalStats.appBytes;
+ mFilePreference.setStorageSize(otherExternalBytes, mTotalSize);
- // We define the system size as everything we can't classify.
if (mSystemPreference != null) {
- mSystemPreference.setStorageSize(
- mUsedBytes
- - data.externalStats.totalBytes
- - data.musicAppsSize
- - data.gamesSize
- - data.videoAppsSize
- - data.otherAppsSize,
- mTotalSize);
+ // Everything else that hasn't already been attributed is tracked as
+ // belonging to system.
+ long attributedSize = 0;
+ for (int i = 0; i < result.size(); i++) {
+ final StorageAsyncLoader.AppsStorageResult otherData = result.valueAt(i);
+ attributedSize += otherData.gamesSize
+ + otherData.musicAppsSize
+ + otherData.videoAppsSize
+ + otherData.otherAppsSize;
+ attributedSize += otherData.externalStats.totalBytes
+ - otherData.externalStats.appBytes;
+ }
+
+ final long systemSize = Math.max(TrafficStats.GB_IN_BYTES, mUsedBytes - attributedSize);
+ mSystemPreference.setStorageSize(systemSize, mTotalSize);
}
}
diff --git a/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java b/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java
index 6440141..779e0b6 100644
--- a/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java
@@ -83,7 +83,7 @@
@Test
public void storageShouldRepresentStorageStatsQuery() throws Exception {
when(mSource.getExternalStorageStats(any(String.class), any(UserHandle.class))).thenReturn(
- new StorageStatsSource.ExternalStorageStats(1, 1, 0, 0));
+ new StorageStatsSource.ExternalStorageStats(1, 1, 0, 0, 0));
mController.queryStats();
mController.setupView(mHolder);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/StorageProfileFragmentTest.java b/tests/robotests/src/com/android/settings/deviceinfo/StorageProfileFragmentTest.java
index 8d48e63..03f15bb 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/StorageProfileFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/StorageProfileFragmentTest.java
@@ -17,6 +17,7 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -31,11 +32,16 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class StorageProfileFragmentTest {
+ @Captor
+ private ArgumentCaptor<SparseArray<StorageAsyncLoader.AppsStorageResult>> mCaptor;
+
@Test
public void verifyAppSizesAreZeroedOut() {
StorageItemPreferenceController controller = mock(StorageItemPreferenceController.class);
@@ -45,18 +51,17 @@
result.otherAppsSize = 200;
result.gamesSize = 300;
result.videoAppsSize = 400;
- result.externalStats = new StorageStatsSource.ExternalStorageStats(6, 1, 2, 3);
+ result.externalStats = new StorageStatsSource.ExternalStorageStats(6, 1, 2, 3, 0);
SparseArray<StorageAsyncLoader.AppsStorageResult> resultsArray = new SparseArray<>();
resultsArray.put(0, result);
fragment.setPreferenceController(controller);
fragment.onLoadFinished(null, resultsArray);
- ArgumentCaptor<StorageAsyncLoader.AppsStorageResult> resultCaptor = ArgumentCaptor.forClass(
- StorageAsyncLoader.AppsStorageResult.class);
- verify(controller).onLoadFinished(resultCaptor.capture());
+ MockitoAnnotations.initMocks(this);
+ verify(controller).onLoadFinished(mCaptor.capture(), anyInt());
- StorageAsyncLoader.AppsStorageResult extractedResult = resultCaptor.getValue();
+ StorageAsyncLoader.AppsStorageResult extractedResult = mCaptor.getValue().get(0);
assertThat(extractedResult.musicAppsSize).isEqualTo(0);
assertThat(extractedResult.videoAppsSize).isEqualTo(0);
assertThat(extractedResult.otherAppsSize).isEqualTo(0);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java
index 32def69..dc1c286 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/SecondaryUserControllerTest.java
@@ -168,7 +168,7 @@
MEGABYTE_IN_BYTES * 30,
MEGABYTE_IN_BYTES * 10,
MEGABYTE_IN_BYTES * 10,
- MEGABYTE_IN_BYTES * 10);
+ MEGABYTE_IN_BYTES * 10, 0);
result.put(10, userResult);
mController.handleResult(result);
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
index e8057a6..3ad3783 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -28,7 +28,6 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
@@ -36,6 +35,7 @@
import android.os.UserHandle;
import android.os.storage.VolumeInfo;
import android.support.v7.preference.PreferenceScreen;
+import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
@@ -275,22 +275,22 @@
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
+ MEGABYTE_IN_BYTES * 200, 0); // image
- mController.onLoadFinished(result);
+ SparseArray<StorageAsyncLoader.AppsStorageResult> results = new SparseArray<>();
+ results.put(0, result);
+ mController.onLoadFinished(results, 0);
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");
}
@@ -488,4 +488,4 @@
verify(screen).addPreference(files);
}
-}
\ No newline at end of file
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/UserProfileControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/UserProfileControllerTest.java
index 8b7110d..2199824 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/UserProfileControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/UserProfileControllerTest.java
@@ -114,7 +114,7 @@
99 * MEGABYTE_IN_BYTES,
33 * MEGABYTE_IN_BYTES,
33 * MEGABYTE_IN_BYTES,
- 33 * MEGABYTE_IN_BYTES);
+ 33 * MEGABYTE_IN_BYTES, 0);
result.put(10, userResult);
mController.handleResult(result);
@@ -141,4 +141,4 @@
Preference preference = argumentCaptor.getValue();
assertThat(preference.getIcon()).isEqualTo(drawable);
}
-}
\ No newline at end of file
+}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java
index 546ea4b..79a4595 100644
--- a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java
@@ -133,9 +133,9 @@
info.id = SECONDARY_USER_ID;
mUsers.add(info);
when(mSource.getExternalStorageStats(anyString(), eq(UserHandle.SYSTEM)))
- .thenReturn(new StorageStatsSource.ExternalStorageStats(9, 2, 3, 4));
+ .thenReturn(new StorageStatsSource.ExternalStorageStats(9, 2, 3, 4, 0));
when(mSource.getExternalStorageStats(anyString(), eq(new UserHandle(SECONDARY_USER_ID))))
- .thenReturn(new StorageStatsSource.ExternalStorageStats(10, 3, 3, 4));
+ .thenReturn(new StorageStatsSource.ExternalStorageStats(10, 3, 3, 4, 0));
SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
@@ -145,19 +145,6 @@
}
@Test
- public void testSystemAppsBaseSizeIsAddedToSystem() throws Exception {
- ApplicationInfo systemApp =
- addPackage(PACKAGE_NAME_1, 100, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
- systemApp.flags = ApplicationInfo.FLAG_SYSTEM;
-
- SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
-
- assertThat(result.size()).isEqualTo(1);
- assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(10L);
- assertThat(result.get(PRIMARY_USER_ID).systemSize).isEqualTo(1L);
- }
-
- @Test
public void testUpdatedSystemAppCodeSizeIsCounted() throws Exception {
ApplicationInfo systemApp =
addPackage(PACKAGE_NAME_1, 100, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);