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

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

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

parents a62b4961 7cec1bc5
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);
    }