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

Commit 7cec1bc5 authored by Daniel Nishi's avatar Daniel Nishi
Browse files

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

Bug: 34204877
Test: Settings Robo
Change-Id: I4a3e26e6e96e9b697c1019160c053b079076d3a2
parent 23eb4378
Loading
Loading
Loading
Loading
+1 −6
Original line number Diff line number Diff line
@@ -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));
+20 −6
Original line number Diff line number Diff line
@@ -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) {
            switch (app.category) {
                case CATEGORY_GAME:
                    result.gamesSize += appSize;
            } else {
                    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;
    }
}
+16 −70
Original line number Diff line number Diff line
@@ -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);

    @Override
    public void onLoaderReset(Loader<AppsAsyncLoader.AppsStorageResult> loader) {
        long unattributedBytes = data.externalStats.totalBytes - data.externalStats.audioBytes
                - data.externalStats.videoBytes - data.externalStats.imageBytes;
        mFilePreference.setStorageSize(unattributedBytes);
    }

    /**
     * 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();
    @Override
    public void onLoaderReset(Loader<StorageAsyncLoader.AppsStorageResult> loader) {
    }

    /**
+13 −17
Original line number Diff line number Diff line
@@ -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");
+7 −7
Original line number Diff line number Diff line
@@ -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);
    }