Use the "fast track" storage calculation for all categories.

Bug: 34204877
Test: Settings Robo
Change-Id: I4a3e26e6e96e9b697c1019160c053b079076d3a2
This commit is contained in:
Daniel Nishi
2017-01-31 12:48:23 -08:00
parent 23eb4378d6
commit 7cec1bc53c
5 changed files with 57 additions and 106 deletions

View File

@@ -17,9 +17,7 @@
package com.android.settings.deviceinfo;
import android.content.Context;
import android.content.Loader;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.provider.SearchIndexableResource;
@@ -29,7 +27,6 @@ import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.PreferenceController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.deviceinfo.storage.AppsAsyncLoader;
import com.android.settings.deviceinfo.storage.StorageItemPreferenceController;
import com.android.settings.deviceinfo.storage.StorageSummaryDonutPreferenceController;
import com.android.settings.overlay.FeatureFactory;
@@ -37,7 +34,6 @@ import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.FooterPreference;
import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
import com.android.settingslib.drawer.CategoryKey;
import java.util.ArrayList;
import java.util.Arrays;
@@ -88,7 +84,6 @@ public class StorageDashboardFragment extends DashboardFragment {
mSummaryController.updateBytes(usedBytes, totalSize);
mPreferenceController.setVolume(mVolume);
mPreferenceController.setSystemSize(systemSize);
mPreferenceController.startMeasurement();
// Initialize the footer preference to go to the smart storage management.
final FooterPreference pref = mFooterPreferenceMixin.createFooterPreference();
@@ -120,7 +115,7 @@ public class StorageDashboardFragment extends DashboardFragment {
controllers.add(mSummaryController);
StorageManager sm = context.getSystemService(StorageManager.class);
mPreferenceController = new StorageItemPreferenceController(context, getLifecycle(), this,
mPreferenceController = new StorageItemPreferenceController(context, this,
mVolume, new StorageManagerVolumeProvider(sm));
controllers.add(mPreferenceController);
controllers.add(new ManageStoragePreferenceController(context));

View File

@@ -16,8 +16,12 @@
package com.android.settings.deviceinfo.storage;
import static android.content.pm.ApplicationInfo.CATEGORY_AUDIO;
import static android.content.pm.ApplicationInfo.CATEGORY_GAME;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.UserHandle;
import android.util.ArraySet;
import com.android.settings.applications.PackageManagerWrapper;
@@ -29,13 +33,13 @@ import java.util.List;
* AppsAsyncLoader is a Loader which loads app storage information and categories it by the app's
* specified categorization.
*/
public class AppsAsyncLoader extends AsyncLoader<AppsAsyncLoader.AppsStorageResult> {
public class StorageAsyncLoader extends AsyncLoader<StorageAsyncLoader.AppsStorageResult> {
private int mUserId;
private String mUuid;
private StorageStatsSource mStatsManager;
private PackageManagerWrapper mPackageManager;
public AppsAsyncLoader(Context context, int userId, String uuid, StorageStatsSource source,
public StorageAsyncLoader(Context context, int userId, String uuid, StorageStatsSource source,
PackageManagerWrapper pm) {
super(context);
mUserId = userId;
@@ -66,12 +70,20 @@ public class AppsAsyncLoader extends AsyncLoader<AppsAsyncLoader.AppsStorageResu
StorageStatsSource.AppStorageStats stats = mStatsManager.getStatsForUid(mUuid, app.uid);
// Note: This omits cache intentionally -- we are not attributing it to the apps.
long appSize = stats.getCodeBytes() + stats.getDataBytes();
if (app.category == ApplicationInfo.CATEGORY_GAME) {
result.gamesSize += appSize;
} else {
result.otherAppsSize += appSize;
switch (app.category) {
case CATEGORY_GAME:
result.gamesSize += appSize;
break;
case CATEGORY_AUDIO:
result.musicAppsSize += appSize;
break;
default:
result.otherAppsSize += appSize;
break;
}
}
result.externalStats = mStatsManager.getExternalStorageStats(mUuid, UserHandle.of(mUserId));
return result;
}
@@ -81,6 +93,8 @@ public class AppsAsyncLoader extends AsyncLoader<AppsAsyncLoader.AppsStorageResu
public static class AppsStorageResult {
public long gamesSize;
public long musicAppsSize;
public long otherAppsSize;
public StorageStatsSource.ExternalStorageStats externalStats;
}
}

View File

@@ -18,13 +18,11 @@ package com.android.settings.deviceinfo.storage;
import android.app.Fragment;
import android.app.LoaderManager;
import android.app.usage.StorageStatsManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.os.Bundle;
import android.os.Environment;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.VolumeInfo;
@@ -40,23 +38,17 @@ import com.android.settings.Utils;
import com.android.settings.applications.ManageApplications;
import com.android.settings.applications.PackageManagerWrapperImpl;
import com.android.settings.core.PreferenceController;
import com.android.settings.core.lifecycle.Lifecycle;
import com.android.settings.core.lifecycle.LifecycleObserver;
import com.android.settings.core.lifecycle.events.OnDestroy;
import com.android.settings.deviceinfo.StorageItemPreference;
import com.android.settingslib.deviceinfo.StorageMeasurement;
import com.android.settingslib.deviceinfo.StorageVolumeProvider;
import java.util.HashMap;
/**
* StorageItemPreferenceController handles the storage line items which summarize the storage
* categorization breakdown.
*/
public class StorageItemPreferenceController extends PreferenceController
implements StorageMeasurement.MeasurementReceiver, LifecycleObserver, OnDestroy,
LoaderManager.LoaderCallbacks<AppsAsyncLoader.AppsStorageResult> {
implements LoaderManager.LoaderCallbacks<StorageAsyncLoader.AppsStorageResult> {
private static final String TAG = "StorageItemPreference";
private static final String IMAGE_MIME_TYPE = "image/*";
@@ -78,9 +70,7 @@ public class StorageItemPreferenceController extends PreferenceController
private final StorageVolumeProvider mSvp;
private VolumeInfo mVolume;
private final int mUserId;
private StorageMeasurement mMeasure;
private long mSystemSize;
private long mUsedSize;
private StorageItemPreferenceAlternate mPhotoPreference;
private StorageItemPreferenceAlternate mAudioPreference;
@@ -91,8 +81,8 @@ public class StorageItemPreferenceController extends PreferenceController
private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents";
public StorageItemPreferenceController(Context context, Lifecycle lifecycle,
Fragment hostFragment, VolumeInfo volume, StorageVolumeProvider svp) {
public StorageItemPreferenceController(
Context context, Fragment hostFragment, VolumeInfo volume, StorageVolumeProvider svp) {
super(context);
mFragment = hostFragment;
mVolume = volume;
@@ -100,10 +90,6 @@ public class StorageItemPreferenceController extends PreferenceController
UserManager um = mContext.getSystemService(UserManager.class);
mUserId = um.getUserHandle();
if (lifecycle != null) {
lifecycle.addObserver(this);
}
}
@Override
@@ -165,44 +151,6 @@ public class StorageItemPreferenceController extends PreferenceController
mVolume = volume;
}
@Override
public void onDetailsChanged(StorageMeasurement.MeasurementDetails details) {
final long imagesSize = totalValues(details, mUserId,
Environment.DIRECTORY_DCIM,
Environment.DIRECTORY_PICTURES,
Environment.DIRECTORY_MOVIES);
if (mPhotoPreference != null) {
mPhotoPreference.setStorageSize(imagesSize);
}
final long audioSize = totalValues(details, mUserId,
Environment.DIRECTORY_MUSIC,
Environment.DIRECTORY_ALARMS,
Environment.DIRECTORY_NOTIFICATIONS,
Environment.DIRECTORY_RINGTONES,
Environment.DIRECTORY_PODCASTS);
if (mAudioPreference != null) {
mAudioPreference.setStorageSize(audioSize);
}
if (mSystemPreference != null) {
mSystemPreference.setStorageSize(mSystemSize);
}
final long downloadsSize = totalValues(details, mUserId, Environment.DIRECTORY_DOWNLOADS);
final long miscSize = details.miscSize.get(mUserId);
if (mFilePreference != null) {
mFilePreference.setStorageSize(downloadsSize + miscSize);
}
}
@Override
public void onDestroy() {
if (mMeasure != null) {
mMeasure.onDestroy();
}
}
@Override
public void displayPreference(PreferenceScreen screen) {
mPhotoPreference = (StorageItemPreferenceAlternate) screen.findPreference(PHOTO_KEY);
@@ -214,32 +162,30 @@ public class StorageItemPreferenceController extends PreferenceController
}
@Override
public Loader<AppsAsyncLoader.AppsStorageResult> onCreateLoader(int id,
public Loader<StorageAsyncLoader.AppsStorageResult> onCreateLoader(int id,
Bundle args) {
return new AppsAsyncLoader(mContext, UserHandle.myUserId(), mVolume.fsUuid,
return new StorageAsyncLoader(mContext, UserHandle.myUserId(), mVolume.fsUuid,
new StorageStatsSource(mContext),
new PackageManagerWrapperImpl(mContext.getPackageManager()));
}
@Override
public void onLoadFinished(Loader<AppsAsyncLoader.AppsStorageResult> loader,
AppsAsyncLoader.AppsStorageResult data) {
public void onLoadFinished(Loader<StorageAsyncLoader.AppsStorageResult> loader,
StorageAsyncLoader.AppsStorageResult data) {
mPhotoPreference.setStorageSize(
data.externalStats.imageBytes + data.externalStats.videoBytes);
mAudioPreference.setStorageSize(data.musicAppsSize + data.externalStats.audioBytes);
mGamePreference.setStorageSize(data.gamesSize);
mAppPreference.setStorageSize(data.otherAppsSize);
mSystemPreference.setStorageSize(mSystemSize);
long unattributedBytes = data.externalStats.totalBytes - data.externalStats.audioBytes
- data.externalStats.videoBytes - data.externalStats.imageBytes;
mFilePreference.setStorageSize(unattributedBytes);
}
@Override
public void onLoaderReset(Loader<AppsAsyncLoader.AppsStorageResult> loader) {
}
/**
* Begins an asynchronous storage measurement task for the preferences.
*/
public void startMeasurement() {
//TODO: When the GID-based measurement system is completed, swap in the GID impl.
mMeasure = new StorageMeasurement(mContext, mVolume, mSvp.findEmulatedForPrivate(mVolume));
mMeasure.setReceiver(this);
mMeasure.forceMeasure();
public void onLoaderReset(Loader<StorageAsyncLoader.AppsStorageResult> loader) {
}
/**

View File

@@ -25,7 +25,6 @@ import static org.mockito.Mockito.when;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.os.UserHandle;
import android.os.storage.VolumeInfo;
import android.provider.DocumentsContract;
@@ -41,7 +40,6 @@ import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.SubSettings;
import com.android.settings.TestConfig;
import com.android.settings.applications.ManageApplications;
import com.android.settingslib.deviceinfo.StorageMeasurement;
import com.android.settingslib.deviceinfo.StorageVolumeProvider;
import org.junit.Before;
@@ -55,8 +53,6 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.HashMap;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class StorageItemPreferenceControllerTest {
@@ -82,7 +78,7 @@ public class StorageItemPreferenceControllerTest {
mContext = RuntimeEnvironment.application;
// Note: null is passed as the Lifecycle because we are handling it outside of the normal
// Settings fragment lifecycle for test purposes.
mController = new StorageItemPreferenceController(mContext, null, mFragment, mVolume, mSvp);
mController = new StorageItemPreferenceController(mContext, mFragment, mVolume, mSvp);
mPreference = new StorageItemPreferenceAlternate(mContext);
// Inflate the preference and the widget.
@@ -205,23 +201,23 @@ public class StorageItemPreferenceControllerTest {
Mockito.eq(StorageItemPreferenceController.FILES_KEY))).thenReturn(files);
mController.displayPreference(screen);
StorageMeasurement.MeasurementDetails details = new StorageMeasurement.MeasurementDetails();
details.appsSize.put(0, KILOBYTE);
HashMap<String, Long> mediaSizes = new HashMap<>();
mediaSizes.put(Environment.DIRECTORY_PICTURES, KILOBYTE * 2);
mediaSizes.put(Environment.DIRECTORY_MOVIES, KILOBYTE * 3);
mediaSizes.put(Environment.DIRECTORY_MUSIC, KILOBYTE * 4);
mediaSizes.put(Environment.DIRECTORY_DOWNLOADS, KILOBYTE * 5);
details.mediaSize.put(0, mediaSizes);
mController.setSystemSize(KILOBYTE * 6);
mController.onDetailsChanged(details);
AppsAsyncLoader.AppsStorageResult result = new AppsAsyncLoader.AppsStorageResult();
StorageAsyncLoader.AppsStorageResult result = new StorageAsyncLoader.AppsStorageResult();
result.gamesSize = KILOBYTE * 8;
result.musicAppsSize = KILOBYTE * 4;
result.otherAppsSize = KILOBYTE * 9;
result.externalStats = new StorageStatsSource.ExternalStorageStats(
KILOBYTE * 50, // total
KILOBYTE * 10, // audio
KILOBYTE * 15, // video
KILOBYTE * 20); // image
result.gamesSize = KILOBYTE * 8;
result.otherAppsSize = KILOBYTE * 9;
mController.onLoadFinished(null, result);
assertThat(audio.getSummary().toString()).isEqualTo("4.00KB");
assertThat(image.getSummary().toString()).isEqualTo("5.00KB");
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(apps.getSummary().toString()).isEqualTo("9.00KB");
assertThat(system.getSummary().toString()).isEqualTo("6.00KB");

View File

@@ -42,7 +42,7 @@ import java.util.ArrayList;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class AppAsyncLoaderTest {
public class StorageAsyncLoaderTest {
@Mock
private StorageStatsSource mSource;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -51,13 +51,13 @@ public class AppAsyncLoaderTest {
private PackageManagerWrapper mPackageManager;
ArrayList<ApplicationInfo> mInfo = new ArrayList<>();
private AppsAsyncLoader mLoader;
private StorageAsyncLoader mLoader;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mInfo = new ArrayList<>();
mLoader = new AppsAsyncLoader(mContext, 1, "id", mSource, mPackageManager);
mLoader = new StorageAsyncLoader(mContext, 1, "id", mSource, mPackageManager);
when(mPackageManager.getInstalledApplicationsAsUser(anyInt(), anyInt())).thenReturn(mInfo);
}
@@ -66,7 +66,7 @@ public class AppAsyncLoaderTest {
addPackage(1001, 0, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
addPackage(1002, 0, 100, 1000, ApplicationInfo.CATEGORY_UNDEFINED);
AppsAsyncLoader.AppsStorageResult result = mLoader.loadInBackground();
StorageAsyncLoader.AppsStorageResult result = mLoader.loadInBackground();
assertThat(result.gamesSize).isEqualTo(0L);
assertThat(result.otherAppsSize).isEqualTo(1111L);
@@ -76,7 +76,7 @@ public class AppAsyncLoaderTest {
public void testGamesAreFiltered() throws Exception {
addPackage(1001, 0, 1, 10, ApplicationInfo.CATEGORY_GAME);
AppsAsyncLoader.AppsStorageResult result = mLoader.loadInBackground();
StorageAsyncLoader.AppsStorageResult result = mLoader.loadInBackground();
assertThat(result.gamesSize).isEqualTo(11L);
assertThat(result.otherAppsSize).isEqualTo(0);
@@ -87,7 +87,7 @@ public class AppAsyncLoaderTest {
addPackage(1001, 0, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
addPackage(1001, 0, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
AppsAsyncLoader.AppsStorageResult result = mLoader.loadInBackground();
StorageAsyncLoader.AppsStorageResult result = mLoader.loadInBackground();
assertThat(result.otherAppsSize).isEqualTo(11L);
}
@@ -96,7 +96,7 @@ public class AppAsyncLoaderTest {
public void testCacheIsIgnored() throws Exception {
addPackage(1001, 100, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
AppsAsyncLoader.AppsStorageResult result = mLoader.loadInBackground();
StorageAsyncLoader.AppsStorageResult result = mLoader.loadInBackground();
assertThat(result.otherAppsSize).isEqualTo(11L);
}