Loading src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java +44 −38 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.content.Intent; import android.net.Uri; import android.os.storage.StorageManager; import android.text.format.Formatter; import android.util.Log; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; Loading @@ -45,10 +44,8 @@ import java.text.NumberFormat; public class LowStorageSlice implements CustomSliceable { private static final String TAG = "LowStorageSlice"; /** * If user used >= 85% storage. * If used storage >= 85%, it would be low storage. */ private static final double LOW_STORAGE_THRESHOLD = 0.85; Loading @@ -60,45 +57,37 @@ public class LowStorageSlice implements CustomSliceable { @Override public Slice getSlice() { // Get current storage percentage from StorageManager. // Get used storage percentage from StorageManager. final PrivateStorageInfo info = PrivateStorageInfo.getPrivateStorageInfo( new StorageManagerVolumeProvider(mContext.getSystemService(StorageManager.class))); final double currentStoragePercentage = (double) (info.totalBytes - info.freeBytes) / info.totalBytes; final double usedPercentage = (double) (info.totalBytes - info.freeBytes) / info.totalBytes; // Generate Low storage Slice. final String percentageString = NumberFormat.getPercentInstance().format(usedPercentage); final String freeSizeString = Formatter.formatFileSize(mContext, info.freeBytes); final ListBuilder listBuilder = new ListBuilder(mContext, CustomSliceRegistry.LOW_STORAGE_SLICE_URI, ListBuilder.INFINITY).setAccentColor( Utils.getColorAccentDefaultColor(mContext)); final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.ic_storage); // Used storage < 85%. NOT show Low storage Slice. if (currentStoragePercentage < LOW_STORAGE_THRESHOLD) { /** * TODO(b/114808204): Contextual Home Page - "Low Storage" * The behavior is under decision making, will update new behavior or remove TODO later. */ Log.i(TAG, "Not show low storage slice, not match condition."); return null; if (usedPercentage < LOW_STORAGE_THRESHOLD) { // For clients that ignore error checking, a generic storage slice will be given. final CharSequence titleStorage = mContext.getText(R.string.storage_settings); final String summaryStorage = mContext.getString(R.string.storage_summary, percentageString, freeSizeString); return listBuilder .addRow(buildRowBuilder(titleStorage, summaryStorage, icon)) .setIsError(true) .build(); } // Show Low storage Slice. final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.ic_storage); final CharSequence title = mContext.getText(R.string.storage_menu_free); final SliceAction primarySliceAction = SliceAction.createDeeplink( PendingIntent.getActivity(mContext, 0, getIntent(), 0), icon, ListBuilder.ICON_IMAGE, title); final String lowStorageSummary = mContext.getString(R.string.low_storage_summary, NumberFormat.getPercentInstance().format(currentStoragePercentage), Formatter.formatFileSize(mContext, info.freeBytes)); final CharSequence titleLowStorage = mContext.getText(R.string.storage_menu_free); final String summaryLowStorage = mContext.getString(R.string.low_storage_summary, percentageString, freeSizeString); /** * TODO(b/114808204): Contextual Home Page - "Low Storage" * Slices doesn't support "Icon on the left" in header. Now we intend to start with Icon * right aligned. Will update the icon to left until Slices support it. */ return new ListBuilder(mContext, CustomSliceRegistry.LOW_STORAGE_SLICE_URI, ListBuilder.INFINITY) .setAccentColor(Utils.getColorAccentDefaultColor(mContext)) .addRow(new RowBuilder() .setTitle(title) .setSubtitle(lowStorageSummary) .addEndItem(icon, ListBuilder.ICON_IMAGE) .setPrimaryAction(primarySliceAction)) return listBuilder .addRow(buildRowBuilder(titleLowStorage, summaryLowStorage, icon)) .build(); } Loading @@ -123,4 +112,21 @@ public class LowStorageSlice implements CustomSliceable { MetricsProto.MetricsEvent.SLICE) .setClassName(mContext.getPackageName(), SubSettings.class.getName()); } private RowBuilder buildRowBuilder(CharSequence title, String summary, IconCompat icon) { final SliceAction primarySliceAction = SliceAction.createDeeplink( PendingIntent.getActivity(mContext, 0, getIntent(), 0), icon, ListBuilder.ICON_IMAGE, title); /** * TODO(b/114808204): Contextual Home Page - "Low Storage" * Slices doesn't support "Icon on the left" in header. Now we intend to start with Icon * right aligned. Will update the icon to left until Slices support it. */ return new RowBuilder() .setTitle(title) .setSubtitle(summary) .addEndItem(icon, ListBuilder.ICON_IMAGE) .setPrimaryAction(primarySliceAction); } } No newline at end of file tests/robotests/src/com/android/settings/homepage/contextualcards/slices/LowStorageSliceTest.java +26 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.settings.homepage.contextualcards.slices; import static android.app.slice.Slice.HINT_ERROR; import static com.google.common.truth.Truth.assertThat; import android.content.Context; Loading Loading @@ -66,7 +68,7 @@ public class LowStorageSliceTest { @Test @Config(shadows = ShadowPrivateStorageInfo.class) public void getSlice_hasLowStorage_shouldBeCorrectSliceContent() { public void getSlice_lowStorage_shouldHaveStorageFreeTitle() { ShadowPrivateStorageInfo.setPrivateStorageInfo(new PrivateStorageInfo(10L, 100L)); final Slice slice = mLowStorageSlice.getSlice(); Loading @@ -77,12 +79,33 @@ public class LowStorageSliceTest { @Test @Config(shadows = ShadowPrivateStorageInfo.class) public void getSlice_hasNoLowStorage_shouldBeNull() { public void getSlice_lowStorage_shouldNotHaveErrorHint() { ShadowPrivateStorageInfo.setPrivateStorageInfo(new PrivateStorageInfo(10L, 100L)); final Slice slice = mLowStorageSlice.getSlice(); assertThat(slice.hasHint(HINT_ERROR)).isFalse(); } @Test @Config(shadows = ShadowPrivateStorageInfo.class) public void getSlice_storageFree_shouldHaveStorageSettingsTitle() { ShadowPrivateStorageInfo.setPrivateStorageInfo(new PrivateStorageInfo(100L, 100L)); final Slice slice = mLowStorageSlice.getSlice(); final List<SliceItem> sliceItems = slice.getItems(); SliceTester.assertTitle(sliceItems, mContext.getString(R.string.storage_settings)); } @Test @Config(shadows = ShadowPrivateStorageInfo.class) public void getSlice_storageFree_shouldHaveErrorHint() { ShadowPrivateStorageInfo.setPrivateStorageInfo(new PrivateStorageInfo(100L, 100L)); final Slice slice = mLowStorageSlice.getSlice(); assertThat(slice).isNull(); assertThat(slice.hasHint(HINT_ERROR)).isTrue(); } @Implements(PrivateStorageInfo.class) Loading Loading
src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java +44 −38 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.content.Intent; import android.net.Uri; import android.os.storage.StorageManager; import android.text.format.Formatter; import android.util.Log; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; Loading @@ -45,10 +44,8 @@ import java.text.NumberFormat; public class LowStorageSlice implements CustomSliceable { private static final String TAG = "LowStorageSlice"; /** * If user used >= 85% storage. * If used storage >= 85%, it would be low storage. */ private static final double LOW_STORAGE_THRESHOLD = 0.85; Loading @@ -60,45 +57,37 @@ public class LowStorageSlice implements CustomSliceable { @Override public Slice getSlice() { // Get current storage percentage from StorageManager. // Get used storage percentage from StorageManager. final PrivateStorageInfo info = PrivateStorageInfo.getPrivateStorageInfo( new StorageManagerVolumeProvider(mContext.getSystemService(StorageManager.class))); final double currentStoragePercentage = (double) (info.totalBytes - info.freeBytes) / info.totalBytes; final double usedPercentage = (double) (info.totalBytes - info.freeBytes) / info.totalBytes; // Generate Low storage Slice. final String percentageString = NumberFormat.getPercentInstance().format(usedPercentage); final String freeSizeString = Formatter.formatFileSize(mContext, info.freeBytes); final ListBuilder listBuilder = new ListBuilder(mContext, CustomSliceRegistry.LOW_STORAGE_SLICE_URI, ListBuilder.INFINITY).setAccentColor( Utils.getColorAccentDefaultColor(mContext)); final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.ic_storage); // Used storage < 85%. NOT show Low storage Slice. if (currentStoragePercentage < LOW_STORAGE_THRESHOLD) { /** * TODO(b/114808204): Contextual Home Page - "Low Storage" * The behavior is under decision making, will update new behavior or remove TODO later. */ Log.i(TAG, "Not show low storage slice, not match condition."); return null; if (usedPercentage < LOW_STORAGE_THRESHOLD) { // For clients that ignore error checking, a generic storage slice will be given. final CharSequence titleStorage = mContext.getText(R.string.storage_settings); final String summaryStorage = mContext.getString(R.string.storage_summary, percentageString, freeSizeString); return listBuilder .addRow(buildRowBuilder(titleStorage, summaryStorage, icon)) .setIsError(true) .build(); } // Show Low storage Slice. final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.ic_storage); final CharSequence title = mContext.getText(R.string.storage_menu_free); final SliceAction primarySliceAction = SliceAction.createDeeplink( PendingIntent.getActivity(mContext, 0, getIntent(), 0), icon, ListBuilder.ICON_IMAGE, title); final String lowStorageSummary = mContext.getString(R.string.low_storage_summary, NumberFormat.getPercentInstance().format(currentStoragePercentage), Formatter.formatFileSize(mContext, info.freeBytes)); final CharSequence titleLowStorage = mContext.getText(R.string.storage_menu_free); final String summaryLowStorage = mContext.getString(R.string.low_storage_summary, percentageString, freeSizeString); /** * TODO(b/114808204): Contextual Home Page - "Low Storage" * Slices doesn't support "Icon on the left" in header. Now we intend to start with Icon * right aligned. Will update the icon to left until Slices support it. */ return new ListBuilder(mContext, CustomSliceRegistry.LOW_STORAGE_SLICE_URI, ListBuilder.INFINITY) .setAccentColor(Utils.getColorAccentDefaultColor(mContext)) .addRow(new RowBuilder() .setTitle(title) .setSubtitle(lowStorageSummary) .addEndItem(icon, ListBuilder.ICON_IMAGE) .setPrimaryAction(primarySliceAction)) return listBuilder .addRow(buildRowBuilder(titleLowStorage, summaryLowStorage, icon)) .build(); } Loading @@ -123,4 +112,21 @@ public class LowStorageSlice implements CustomSliceable { MetricsProto.MetricsEvent.SLICE) .setClassName(mContext.getPackageName(), SubSettings.class.getName()); } private RowBuilder buildRowBuilder(CharSequence title, String summary, IconCompat icon) { final SliceAction primarySliceAction = SliceAction.createDeeplink( PendingIntent.getActivity(mContext, 0, getIntent(), 0), icon, ListBuilder.ICON_IMAGE, title); /** * TODO(b/114808204): Contextual Home Page - "Low Storage" * Slices doesn't support "Icon on the left" in header. Now we intend to start with Icon * right aligned. Will update the icon to left until Slices support it. */ return new RowBuilder() .setTitle(title) .setSubtitle(summary) .addEndItem(icon, ListBuilder.ICON_IMAGE) .setPrimaryAction(primarySliceAction); } } No newline at end of file
tests/robotests/src/com/android/settings/homepage/contextualcards/slices/LowStorageSliceTest.java +26 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.settings.homepage.contextualcards.slices; import static android.app.slice.Slice.HINT_ERROR; import static com.google.common.truth.Truth.assertThat; import android.content.Context; Loading Loading @@ -66,7 +68,7 @@ public class LowStorageSliceTest { @Test @Config(shadows = ShadowPrivateStorageInfo.class) public void getSlice_hasLowStorage_shouldBeCorrectSliceContent() { public void getSlice_lowStorage_shouldHaveStorageFreeTitle() { ShadowPrivateStorageInfo.setPrivateStorageInfo(new PrivateStorageInfo(10L, 100L)); final Slice slice = mLowStorageSlice.getSlice(); Loading @@ -77,12 +79,33 @@ public class LowStorageSliceTest { @Test @Config(shadows = ShadowPrivateStorageInfo.class) public void getSlice_hasNoLowStorage_shouldBeNull() { public void getSlice_lowStorage_shouldNotHaveErrorHint() { ShadowPrivateStorageInfo.setPrivateStorageInfo(new PrivateStorageInfo(10L, 100L)); final Slice slice = mLowStorageSlice.getSlice(); assertThat(slice.hasHint(HINT_ERROR)).isFalse(); } @Test @Config(shadows = ShadowPrivateStorageInfo.class) public void getSlice_storageFree_shouldHaveStorageSettingsTitle() { ShadowPrivateStorageInfo.setPrivateStorageInfo(new PrivateStorageInfo(100L, 100L)); final Slice slice = mLowStorageSlice.getSlice(); final List<SliceItem> sliceItems = slice.getItems(); SliceTester.assertTitle(sliceItems, mContext.getString(R.string.storage_settings)); } @Test @Config(shadows = ShadowPrivateStorageInfo.class) public void getSlice_storageFree_shouldHaveErrorHint() { ShadowPrivateStorageInfo.setPrivateStorageInfo(new PrivateStorageInfo(100L, 100L)); final Slice slice = mLowStorageSlice.getSlice(); assertThat(slice).isNull(); assertThat(slice.hasHint(HINT_ERROR)).isTrue(); } @Implements(PrivateStorageInfo.class) Loading