Merge "Shows trash category in Storage Settings" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
90c29cf014
@@ -18,7 +18,8 @@
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
android:viewportHeight="24"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:pathData="M15,3V4H20V6H19V19C19,20.1 18.1,21 17,21H7C5.9,21 5,20.1 5,19V6H4V4H9V3H15ZM7,19H17V6H7V19ZM9,8H11V17H9V8ZM15,8H13V17H15V8Z"
|
||||
android:fillColor="#5F6368"
|
||||
|
@@ -17,8 +17,6 @@
|
||||
package com.android.settings.deviceinfo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
@@ -26,6 +24,7 @@ import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.deviceinfo.storage.StorageUtils;
|
||||
|
||||
public class StorageItemPreference extends Preference {
|
||||
public int userHandle;
|
||||
@@ -49,7 +48,7 @@ public class StorageItemPreference extends Preference {
|
||||
|
||||
public void setStorageSize(long size, long total) {
|
||||
mStorageSize = size;
|
||||
setSummary(getStorageSummary(size));
|
||||
setSummary(StorageUtils.getStorageSizeLabel(getContext(), size));
|
||||
|
||||
if (total == 0) {
|
||||
mProgressPercent = 0;
|
||||
@@ -77,11 +76,4 @@ public class StorageItemPreference extends Preference {
|
||||
updateProgressBar();
|
||||
super.onBindViewHolder(view);
|
||||
}
|
||||
|
||||
private String getStorageSummary(long bytes) {
|
||||
final Formatter.BytesResult result = Formatter.formatBytes(getContext().getResources(),
|
||||
bytes, Formatter.FLAG_SHORTER);
|
||||
return TextUtils.expandTemplate(getContext().getText(R.string.storage_size_large),
|
||||
result.value, result.units).toString();
|
||||
}
|
||||
}
|
||||
|
@@ -18,25 +18,54 @@ package com.android.settings.deviceinfo.storage;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
/**
|
||||
* Dialog asks if users want to empty trash files.
|
||||
* TODO(b/189388449): Shows "Deleting..." and disables Trash category while deleting trash files.
|
||||
*/
|
||||
public class EmptyTrashFragment extends InstrumentedDialogFragment {
|
||||
private static final String TAG = "EmptyTrashFragment";
|
||||
|
||||
private static final String TAG_EMPTY_TRASH = "empty_trash";
|
||||
|
||||
private final Fragment mParentFragment;
|
||||
private final int mUserId;
|
||||
private final long mTrashSize;
|
||||
private final OnEmptyTrashCompleteListener mOnEmptyTrashCompleteListener;
|
||||
|
||||
/** The listener to receive empty trash complete callback event. */
|
||||
public interface OnEmptyTrashCompleteListener {
|
||||
/** The empty trash complete callback. */
|
||||
void onEmptyTrashComplete();
|
||||
}
|
||||
|
||||
public EmptyTrashFragment(Fragment parent, int userId, long trashSize,
|
||||
OnEmptyTrashCompleteListener onEmptyTrashCompleteListener) {
|
||||
super();
|
||||
|
||||
mParentFragment = parent;
|
||||
setTargetFragment(mParentFragment, 0 /* requestCode */);
|
||||
mUserId = userId;
|
||||
mTrashSize = trashSize;
|
||||
mOnEmptyTrashCompleteListener = onEmptyTrashCompleteListener;
|
||||
}
|
||||
|
||||
/** Shows the empty trash dialog. */
|
||||
public static void show(Fragment parent) {
|
||||
final EmptyTrashFragment dialog = new EmptyTrashFragment();
|
||||
dialog.setTargetFragment(parent, 0 /* requestCode */);
|
||||
dialog.show(parent.getFragmentManager(), TAG_EMPTY_TRASH);
|
||||
public void show() {
|
||||
show(mParentFragment.getFragmentManager(), TAG_EMPTY_TRASH);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,10 +77,38 @@ public class EmptyTrashFragment extends InstrumentedDialogFragment {
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
return builder.setTitle(R.string.storage_trash_dialog_title)
|
||||
.setMessage(R.string.storage_trash_dialog_ask_message)
|
||||
.setPositiveButton(R.string.storage_trash_dialog_confirm, (dialog, which) -> {
|
||||
// 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());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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<Void, Void, Exception> {
|
||||
private final Context mContext;
|
||||
|
Reference in New Issue
Block a user