diff --git a/res/drawable/ic_trash_can.xml b/res/drawable/ic_trash_can.xml index ed4a4cbbd09..7829e1b9f8a 100644 --- a/res/drawable/ic_trash_can.xml +++ b/res/drawable/ic_trash_can.xml @@ -18,7 +18,8 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24"> + android:viewportHeight="24" + android:tint="?android:attr/colorControlNormal"> { - // TODO(170918505): Implement the logic in worker thread. - }).setNegativeButton(android.R.string.cancel, null) + .setMessage(getActivity().getString(R.string.storage_trash_dialog_ask_message, + StorageUtils.getStorageSizeLabel(getActivity(), mTrashSize))) + .setPositiveButton(R.string.storage_trash_dialog_confirm, + (dialog, which) -> emptyTrashAsync()) + .setNegativeButton(android.R.string.cancel, null) .create(); } + + private void emptyTrashAsync() { + final Context context = getActivity(); + final Context perUserContext; + try { + perUserContext = context.createPackageContextAsUser( + context.getApplicationContext().getPackageName(), + 0 /* flags= */, + UserHandle.of(mUserId)); + } catch (NameNotFoundException e) { + Log.e(TAG, "Not able to get Context for user ID " + mUserId); + return; + } + + final Bundle trashQueryArgs = new Bundle(); + trashQueryArgs.putInt(MediaStore.QUERY_ARG_MATCH_TRASHED, MediaStore.MATCH_ONLY); + ThreadUtils.postOnBackgroundThread(() -> { + perUserContext.getContentResolver().delete( + MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL), + trashQueryArgs); + if (mOnEmptyTrashCompleteListener == null) { + return; + } + ThreadUtils.postOnMainThread( + () -> mOnEmptyTrashCompleteListener.onEmptyTrashComplete()); + }); + } } diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java index 67a5bb7f49d..d57d81ef7f8 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java +++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java @@ -32,6 +32,7 @@ import android.os.UserManager; import android.os.storage.VolumeInfo; import android.util.Log; import android.util.SparseArray; +import android.widget.Toast; import androidx.annotation.VisibleForTesting; import androidx.fragment.app.Fragment; @@ -64,7 +65,8 @@ import java.util.Map; * categorization breakdown. */ public class StorageItemPreferenceController extends AbstractPreferenceController implements - PreferenceControllerMixin { + PreferenceControllerMixin, + EmptyTrashFragment.OnEmptyTrashCompleteListener { private static final String TAG = "StorageItemPreference"; private static final String SYSTEM_FRAGMENT_TAG = "SystemInfo"; @@ -256,8 +258,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle mGamesPreference.setVisible(privateStoragePreferencesVisible); mDocumentsAndOtherPreference.setVisible(privateStoragePreferencesVisible); mSystemPreference.setVisible(privateStoragePreferencesVisible); - // TODO(b/170918505): Shows trash category after trash category feature complete. - mTrashPreference.setVisible(false); + mTrashPreference.setVisible(privateStoragePreferencesVisible); if (privateStoragePreferencesVisible) { final VolumeInfo sharedVolume = mSvp.findEmulatedForPrivate(mVolume); @@ -460,13 +461,29 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle private void launchTrashIntent() { final Intent intent = new Intent("android.settings.VIEW_TRASH"); - if (intent.resolveActivity(mPackageManager) == null) { - EmptyTrashFragment.show(mFragment); + if (mPackageManager.resolveActivityAsUser(intent, 0 /* flags */, mUserId) == null) { + final long trashSize = mTrashPreference.getStorageSize(); + if (trashSize > 0) { + new EmptyTrashFragment(mFragment, mUserId, trashSize, + this /* onEmptyTrashCompleteListener */).show(); + } else { + Toast.makeText(mContext, R.string.storage_trash_dialog_empty_message, + Toast.LENGTH_SHORT).show(); + } } else { mContext.startActivityAsUser(intent, new UserHandle(mUserId)); } } + @Override + public void onEmptyTrashComplete() { + if (mTrashPreference == null) { + return; + } + mTrashPreference.setStorageSize(0, mTotalSize); + updatePrivateStorageCategoryPreferencesOrder(); + } + private static long totalValues(StorageMeasurement.MeasurementDetails details, int userId, String... keys) { long total = 0; diff --git a/src/com/android/settings/deviceinfo/storage/StorageUtils.java b/src/com/android/settings/deviceinfo/storage/StorageUtils.java index 549eef61f7f..9b52fe803b1 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageUtils.java +++ b/src/com/android/settings/deviceinfo/storage/StorageUtils.java @@ -26,6 +26,8 @@ import android.os.storage.DiskInfo; import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; import android.os.storage.VolumeRecord; +import android.text.TextUtils; +import android.text.format.Formatter; import android.util.Log; import android.widget.Toast; @@ -115,6 +117,14 @@ public class StorageUtils { .launch(); } + /** Returns size label of changing units. (e.g., 1kB, 2MB, 3GB) */ + public static String getStorageSizeLabel(Context context, long bytes) { + final Formatter.BytesResult result = Formatter.formatBytes(context.getResources(), + bytes, Formatter.FLAG_SHORTER); + return TextUtils.expandTemplate(context.getText(R.string.storage_size_large), + result.value, result.units).toString(); + } + /** An AsyncTask to unmount a specified volume. */ public static class UnmountTask extends AsyncTask { private final Context mContext;