Split System category

Splitting System category in
Settings > Storage into "Android 14"
and "Temporary system files".

Android 14 is calculated as
StorageStatsManager#getTotalBytes - (size of /data partition).
Basically it's the size of all partitions
except for the userdata. It also includes
the storage rounding which we do to display
a nice round storage size (128GB, 256GB, etc).

Temporary System Files serves as "Everything else"
category that represents all the used storage
that didn't fall under any other category.
It's the same as how currently "System" category works.

Bug: 309801699
Test: atest StorageItemPreferenceControllerTest
Test: atest StorageCacheHelperTest
Change-Id: Ifae5819bf1d7a1a675df1fa67bd6dcdfa074b584
This commit is contained in:
alukin
2024-03-12 16:30:24 +00:00
parent c35fc38be9
commit f4329ada00
10 changed files with 201 additions and 25 deletions

View File

@@ -30,8 +30,10 @@ import android.content.pm.UserInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.provider.MediaStore;
import android.provider.MediaStore.Files.FileColumns;
import android.provider.MediaStore.MediaColumns;
@@ -94,6 +96,7 @@ public class StorageAsyncLoader
media /* queryArgs */);
result.audioSize = getFilesSize(info.id, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
media /* queryArgs */);
result.systemSize = getSystemSize();
final Bundle documentsAndOtherQueryArgs = new Bundle();
documentsAndOtherQueryArgs.putString(ContentResolver.QUERY_ARG_SQL_SELECTION,
@@ -140,6 +143,16 @@ public class StorageAsyncLoader
}
}
private long getSystemSize() {
try {
return mStatsManager.getTotalBytes(StorageManager.UUID_DEFAULT)
- Environment.getDataDirectory().getTotalSpace();
} catch (IOException e) {
Log.e(TAG, "Exception in calculating System category size", e);
return 0;
}
}
private StorageResult getAppsAndGamesSize(int userId) {
Log.d(TAG, "Loading apps");
final List<ApplicationInfo> applicationInfos =
@@ -225,6 +238,7 @@ public class StorageAsyncLoader
public long videosSize;
public long documentsAndOtherSize;
public long trashSize;
public long systemSize;
public long cacheSize;
public long duplicateCodeSize;

View File

@@ -35,6 +35,7 @@ public class StorageCacheHelper {
private static final String DOCUMENTS_AND_OTHER_SIZE_KEY = "documents_and_other_size_key";
private static final String TRASH_SIZE_KEY = "trash_size_key";
private static final String SYSTEM_SIZE_KEY = "system_size_key";
private static final String TEMPORARY_FILES_SIZE_KEY = "temporary_files_size_key";
private static final String USED_SIZE_KEY = "used_size_key";
private final SharedPreferences mSharedPreferences;
@@ -66,6 +67,7 @@ public class StorageCacheHelper {
.putLong(DOCUMENTS_AND_OTHER_SIZE_KEY, data.documentsAndOtherSize)
.putLong(TRASH_SIZE_KEY, data.trashSize)
.putLong(SYSTEM_SIZE_KEY, data.systemSize)
.putLong(TEMPORARY_FILES_SIZE_KEY, data.temporaryFilesSize)
.apply();
}
@@ -109,6 +111,7 @@ public class StorageCacheHelper {
result.documentsAndOtherSize = mSharedPreferences.getLong(DOCUMENTS_AND_OTHER_SIZE_KEY, 0);
result.trashSize = mSharedPreferences.getLong(TRASH_SIZE_KEY, 0);
result.systemSize = mSharedPreferences.getLong(SYSTEM_SIZE_KEY, 0);
result.temporaryFilesSize = mSharedPreferences.getLong(TEMPORARY_FILES_SIZE_KEY, 0);
return result;
}
@@ -126,5 +129,6 @@ public class StorageCacheHelper {
public long documentsAndOtherSize;
public long trashSize;
public long systemSize;
public long temporaryFilesSize;
}
}

View File

@@ -27,6 +27,7 @@ import android.content.pm.UserInfo;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
@@ -40,6 +41,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
@@ -52,6 +54,7 @@ import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.deviceinfo.StorageItemPreference;
import com.android.settings.deviceinfo.storage.StorageUtils.SystemInfoFragment;
import com.android.settings.deviceinfo.storage.StorageUtils.TemporaryFilesInfoFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -74,6 +77,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
private static final String TAG = "StorageItemPreference";
private static final String SYSTEM_FRAGMENT_TAG = "SystemInfo";
private static final String TEMPORARY_FILES_FRAGMENT_TAG = "TemporaryFilesInfo";
@VisibleForTesting
static final String PUBLIC_STORAGE_KEY = "pref_public_storage";
@@ -92,6 +96,10 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
@VisibleForTesting
static final String SYSTEM_KEY = "pref_system";
@VisibleForTesting
static final String TEMPORARY_FILES_KEY = "temporary_files";
@VisibleForTesting
static final String CATEGORY_SPLITTER = "storage_category_splitter";
@VisibleForTesting
static final String TRASH_KEY = "pref_trash";
@VisibleForTesting
@@ -133,9 +141,13 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
@VisibleForTesting
@Nullable StorageItemPreference mDocumentsAndOtherPreference;
@VisibleForTesting
@Nullable StorageItemPreference mTrashPreference;
@VisibleForTesting
@Nullable StorageItemPreference mSystemPreference;
@VisibleForTesting
@Nullable StorageItemPreference mTrashPreference;
@Nullable StorageItemPreference mTemporaryFilesPreference;
@VisibleForTesting
@Nullable PreferenceCategory mCategorySplitterPreferenceCategory;
private final int mProfileType;
@@ -220,6 +232,13 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
dialog.setTargetFragment(mFragment, 0);
dialog.show(mFragment.getFragmentManager(), SYSTEM_FRAGMENT_TAG);
return true;
case TEMPORARY_FILES_KEY:
final TemporaryFilesInfoFragment temporaryFilesDialog =
new TemporaryFilesInfoFragment();
temporaryFilesDialog.setTargetFragment(mFragment, 0);
temporaryFilesDialog.show(mFragment.getFragmentManager(),
TEMPORARY_FILES_FRAGMENT_TAG);
return true;
case TRASH_KEY:
launchTrashIntent();
return true;
@@ -285,6 +304,8 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mAppsPreference.setVisible(visible);
mGamesPreference.setVisible(visible);
mSystemPreference.setVisible(visible);
mTemporaryFilesPreference.setVisible(visible);
mCategorySplitterPreferenceCategory.setVisible(visible);
mTrashPreference.setVisible(visible);
// If we don't have a shared volume for our internal storage (or the shared volume isn't
@@ -315,7 +336,6 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mPrivateStorageItemPreferences.add(mAppsPreference);
mPrivateStorageItemPreferences.add(mGamesPreference);
mPrivateStorageItemPreferences.add(mDocumentsAndOtherPreference);
mPrivateStorageItemPreferences.add(mSystemPreference);
mPrivateStorageItemPreferences.add(mTrashPreference);
}
mScreen.removePreference(mImagesPreference);
@@ -324,7 +344,6 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mScreen.removePreference(mAppsPreference);
mScreen.removePreference(mGamesPreference);
mScreen.removePreference(mDocumentsAndOtherPreference);
mScreen.removePreference(mSystemPreference);
mScreen.removePreference(mTrashPreference);
// Sort display order by size.
@@ -361,6 +380,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
tintPreference(mGamesPreference);
tintPreference(mDocumentsAndOtherPreference);
tintPreference(mSystemPreference);
tintPreference(mTemporaryFilesPreference);
tintPreference(mTrashPreference);
}
@@ -389,7 +409,9 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mAppsPreference = screen.findPreference(APPS_KEY);
mGamesPreference = screen.findPreference(GAMES_KEY);
mDocumentsAndOtherPreference = screen.findPreference(DOCUMENTS_AND_OTHER_KEY);
mCategorySplitterPreferenceCategory = screen.findPreference(CATEGORY_SPLITTER);
mSystemPreference = screen.findPreference(SYSTEM_KEY);
mTemporaryFilesPreference = screen.findPreference(TEMPORARY_FILES_KEY);
mTrashPreference = screen.findPreference(TRASH_KEY);
}
@@ -417,6 +439,12 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
mTrashPreference.setStorageSize(storageCache.trashSize, mTotalSize, animate);
if (mSystemPreference != null) {
mSystemPreference.setStorageSize(storageCache.systemSize, mTotalSize, animate);
mSystemPreference.setTitle(mContext.getString(R.string.storage_os_name,
Build.VERSION.RELEASE));
}
if (mTemporaryFilesPreference != null) {
mTemporaryFilesPreference.setStorageSize(storageCache.temporaryFilesSize, mTotalSize,
animate);
}
// Cache the size info
if (result != null) {
@@ -445,6 +473,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
storageCache.gamesSize = data.gamesSize;
storageCache.documentsAndOtherSize = data.documentsAndOtherSize;
storageCache.trashSize = data.trashSize;
storageCache.systemSize = data.systemSize;
// Everything else that hasn't already been attributed is tracked as
// belonging to system.
long attributedSize = 0;
@@ -460,7 +489,9 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
+ otherData.allAppsExceptGamesSize;
attributedSize -= otherData.duplicateCodeSize;
}
storageCache.systemSize = Math.max(DataUnit.GIBIBYTES.toBytes(1),
// System size is equal for each user and should be added only once
attributedSize += data.systemSize;
storageCache.temporaryFilesSize = Math.max(DataUnit.GIBIBYTES.toBytes(1),
mUsedBytes - attributedSize);
return storageCache;
}

View File

@@ -23,7 +23,6 @@ import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.storage.DiskInfo;
import android.os.storage.StorageManager;
@@ -34,6 +33,7 @@ import android.text.format.Formatter;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
@@ -206,7 +206,7 @@ public class StorageUtils {
/** Shows information about system storage. */
public static class SystemInfoFragment extends InstrumentedDialogFragment {
/** Shows the fragment. */
public static void show(Fragment parent) {
public static void show(@NonNull Fragment parent) {
if (!parent.isAdded()) return;
final SystemInfoFragment dialog = new SystemInfoFragment();
@@ -222,8 +222,33 @@ public class StorageUtils {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setMessage(getContext().getString(R.string.storage_detail_dialog_system,
Build.VERSION.RELEASE_OR_PREVIEW_DISPLAY))
.setMessage(getContext().getString(R.string.storage_os_detail_dialog_system))
.setPositiveButton(android.R.string.ok, null)
.create();
}
}
/** Shows information about temporary system files. */
public static class TemporaryFilesInfoFragment extends InstrumentedDialogFragment {
/** Shows the fragment. */
public static void show(@NonNull Fragment parent) {
if (!parent.isAdded()) return;
final TemporaryFilesInfoFragment dialog = new TemporaryFilesInfoFragment();
dialog.setTargetFragment(parent, 0);
dialog.show(parent.getFragmentManager(), "temporaryFilesInfo");
}
@Override
public int getMetricsCategory() {
return SettingsEnums.DIALOG_TEMPORARY_FILES_INFO;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setMessage(getContext().getString(
R.string.storage_other_files_detail_dialog_system))
.setPositiveButton(android.R.string.ok, null)
.create();
}