diff --git a/res/drawable/ic_android_vd_theme_24.xml b/res/drawable/ic_android_vd_theme_24.xml
new file mode 100644
index 00000000000..65812090007
--- /dev/null
+++ b/res/drawable/ic_android_vd_theme_24.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
diff --git a/res/drawable/ic_database_vd_theme_24.xml b/res/drawable/ic_database_vd_theme_24.xml
new file mode 100644
index 00000000000..713a65e9c57
--- /dev/null
+++ b/res/drawable/ic_database_vd_theme_24.xml
@@ -0,0 +1,25 @@
+
+
+
+
diff --git a/res/xml/storage_category_fragment.xml b/res/xml/storage_category_fragment.xml
index 2c9588938a2..58bd89138df 100644
--- a/res/xml/storage_category_fragment.xml
+++ b/res/xml/storage_category_fragment.xml
@@ -61,19 +61,31 @@
android:title="@string/storage_documents_and_other"
android:icon="@drawable/ic_folder_vd_theme_24"
android:order="106"/>
-
-
+ android:order="107"/>
+
+
+
+
+
+ android:order="204" />
diff --git a/res/xml/storage_dashboard_fragment.xml b/res/xml/storage_dashboard_fragment.xml
index 7c0f3a6d195..fd866ad8604 100644
--- a/res/xml/storage_dashboard_fragment.xml
+++ b/res/xml/storage_dashboard_fragment.xml
@@ -80,19 +80,31 @@
android:title="@string/storage_documents_and_other"
android:icon="@drawable/ic_folder_vd_theme_24"
android:order="106"/>
-
-
+ android:order="107"/>
+
+
+
+
+
+ android:order="204" />
diff --git a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
index 54935ecf4de..4906cf2d8d8 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
@@ -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 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;
diff --git a/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java b/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java
index e6da454f2f1..50690cb0791 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageCacheHelper.java
@@ -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;
}
}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index fd424178f0c..62422ca1ea5 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -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;
}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageUtils.java b/src/com/android/settings/deviceinfo/storage/StorageUtils.java
index 4b6a2c40fd8..5c4a4b40f2a 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageUtils.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageUtils.java
@@ -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();
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java
index 9e20e78c03a..a26ea1dfca2 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageCacheHelperTest.java
@@ -41,6 +41,7 @@ public class StorageCacheHelperTest {
private static final long FAKE_TOTAL_SIZE = 256000L;
private static final long FAKE_TOTAL_USED_SIZE = 50000L;
private static final long FAKE_USED_SIZE = 6500L;
+ private static final long FAKE_TEMPORARY_FILES_SIZE = 2500L;
private Context mContext;
private StorageCacheHelper mHelper;
@@ -70,6 +71,7 @@ public class StorageCacheHelperTest {
StorageCacheHelper.StorageCache storageCache = mHelper.retrieveCachedSize();
assertThat(storageCache.imagesSize).isEqualTo(FAKE_IMAGES_SIZE);
+ assertThat(storageCache.temporaryFilesSize).isEqualTo(FAKE_TEMPORARY_FILES_SIZE);
assertThat(storageCache.totalSize).isEqualTo(0);
}
@@ -100,6 +102,7 @@ public class StorageCacheHelperTest {
result.gamesSize = FAKE_GAMES_SIZE;
result.videosSize = FAKE_VIDEOS_SIZE;
result.allAppsExceptGamesSize = FAKE_APPS_SIZE;
+ result.temporaryFilesSize = FAKE_TEMPORARY_FILES_SIZE;
return 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 b61f5ab4ef4..2590f52340f 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -45,6 +45,7 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
+import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
@@ -126,7 +127,10 @@ public class StorageItemPreferenceControllerTest {
final StorageItemPreference documentsAndOther = spy(new StorageItemPreference(mContext));
documentsAndOther.setIcon(R.drawable.ic_folder_vd_theme_24);
final StorageItemPreference system = spy(new StorageItemPreference(mContext));
- system.setIcon(com.android.settingslib.R.drawable.ic_system_update);
+ system.setIcon(R.drawable.ic_android_vd_theme_24);
+ final StorageItemPreference temporaryFiles = spy(new StorageItemPreference(mContext));
+ temporaryFiles.setIcon(R.drawable.ic_database_vd_theme_24);
+ final PreferenceCategory categorySplitter = spy(new PreferenceCategory(mContext));
final StorageItemPreference trash = spy(new StorageItemPreference(mContext));
trash.setIcon(R.drawable.ic_trash_can);
@@ -147,6 +151,10 @@ public class StorageItemPreferenceControllerTest {
.thenReturn(documentsAndOther);
when(screen.findPreference(eq(StorageItemPreferenceController.SYSTEM_KEY)))
.thenReturn(system);
+ when(screen.findPreference(eq(StorageItemPreferenceController.TEMPORARY_FILES_KEY)))
+ .thenReturn(temporaryFiles);
+ when(screen.findPreference(eq(StorageItemPreferenceController.CATEGORY_SPLITTER)))
+ .thenReturn(categorySplitter);
when(screen.findPreference(eq(StorageItemPreferenceController.TRASH_KEY)))
.thenReturn(trash);
@@ -219,6 +227,7 @@ public class StorageItemPreferenceControllerTest {
assertThat(mController.mGamesPreference.isVisible()).isFalse();
assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
assertThat(mController.mSystemPreference.isVisible()).isFalse();
+ assertThat(mController.mTemporaryFilesPreference.isVisible()).isFalse();
assertThat(mController.mTrashPreference.isVisible()).isFalse();
}
@@ -329,6 +338,16 @@ public class StorageItemPreferenceControllerTest {
.add(nullable(StorageUtils.SystemInfoFragment.class), nullable(String.class));
}
+ @Test
+ public void testClickTemporaryFiles() {
+ mPreference.setKey(StorageItemPreferenceController.TEMPORARY_FILES_KEY);
+ assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
+
+ verify(mFragment.getFragmentManager().beginTransaction())
+ .add(nullable(StorageUtils.TemporaryFilesInfoFragment.class),
+ nullable(String.class));
+ }
+
@Test
@Config(shadows = ShadowUserManager.class)
public void testMeasurementCompletedUpdatesPreferences() {
@@ -343,6 +362,7 @@ public class StorageItemPreferenceControllerTest {
result.documentsAndOtherSize = MEGABYTE_IN_BYTES * 50;
result.trashSize = KILOBYTE_IN_BYTES * 100;
result.allAppsExceptGamesSize = MEGABYTE_IN_BYTES * 90;
+ result.systemSize = MEGABYTE_IN_BYTES * 60;
final SparseArray results = new SparseArray<>();
results.put(0, result);
@@ -356,6 +376,8 @@ public class StorageItemPreferenceControllerTest {
assertThat(mController.mDocumentsAndOtherPreference.getSummary().toString())
.isEqualTo("50 MB");
assertThat(mController.mTrashPreference.getSummary().toString()).isEqualTo("100 kB");
+ assertThat(mController.mSystemPreference.getSummary().toString())
+ .isEqualTo("60 MB");
}
@Test
@@ -373,6 +395,7 @@ public class StorageItemPreferenceControllerTest {
verify(mController.mDocumentsAndOtherPreference, times(2))
.setIcon(nullable(Drawable.class));
verify(mController.mSystemPreference, times(2)).setIcon(nullable(Drawable.class));
+ verify(mController.mTemporaryFilesPreference, times(2)).setIcon(nullable(Drawable.class));
verify(mController.mTrashPreference, times(2)).setIcon(nullable(Drawable.class));
}
@@ -437,6 +460,7 @@ public class StorageItemPreferenceControllerTest {
assertThat(mController.mGamesPreference.isVisible()).isFalse();
assertThat(mController.mDocumentsAndOtherPreference.isVisible()).isFalse();
assertThat(mController.mSystemPreference.isVisible()).isFalse();
+ assertThat(mController.mTemporaryFilesPreference.isVisible()).isFalse();
assertThat(mController.mTrashPreference.isVisible()).isFalse();
}