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:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24">
|
android:viewportHeight="24"
|
||||||
|
android:tint="?android:attr/colorControlNormal">
|
||||||
<path
|
<path
|
||||||
android:pathData="M15,3V4H20V6H19V19C19,20.1 18.1,21 17,21H7C5.9,21 5,20.1 5,19V6H4V4H9V3H15ZM7,19H17V6H7V19ZM9,8H11V17H9V8ZM15,8H13V17H15V8Z"
|
android:pathData="M15,3V4H20V6H19V19C19,20.1 18.1,21 17,21H7C5.9,21 5,20.1 5,19V6H4V4H9V3H15ZM7,19H17V6H7V19ZM9,8H11V17H9V8ZM15,8H13V17H15V8Z"
|
||||||
android:fillColor="#5F6368"
|
android:fillColor="#5F6368"
|
||||||
|
@@ -17,8 +17,6 @@
|
|||||||
package com.android.settings.deviceinfo;
|
package com.android.settings.deviceinfo;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.text.format.Formatter;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
@@ -26,6 +24,7 @@ import androidx.preference.Preference;
|
|||||||
import androidx.preference.PreferenceViewHolder;
|
import androidx.preference.PreferenceViewHolder;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.deviceinfo.storage.StorageUtils;
|
||||||
|
|
||||||
public class StorageItemPreference extends Preference {
|
public class StorageItemPreference extends Preference {
|
||||||
public int userHandle;
|
public int userHandle;
|
||||||
@@ -49,7 +48,7 @@ public class StorageItemPreference extends Preference {
|
|||||||
|
|
||||||
public void setStorageSize(long size, long total) {
|
public void setStorageSize(long size, long total) {
|
||||||
mStorageSize = size;
|
mStorageSize = size;
|
||||||
setSummary(getStorageSummary(size));
|
setSummary(StorageUtils.getStorageSizeLabel(getContext(), size));
|
||||||
|
|
||||||
if (total == 0) {
|
if (total == 0) {
|
||||||
mProgressPercent = 0;
|
mProgressPercent = 0;
|
||||||
@@ -77,11 +76,4 @@ public class StorageItemPreference extends Preference {
|
|||||||
updateProgressBar();
|
updateProgressBar();
|
||||||
super.onBindViewHolder(view);
|
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.Dialog;
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.provider.MediaStore;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog asks if users want to empty trash files.
|
* 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 {
|
public class EmptyTrashFragment extends InstrumentedDialogFragment {
|
||||||
|
private static final String TAG = "EmptyTrashFragment";
|
||||||
|
|
||||||
private static final String TAG_EMPTY_TRASH = "empty_trash";
|
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. */
|
/** Shows the empty trash dialog. */
|
||||||
public static void show(Fragment parent) {
|
public void show() {
|
||||||
final EmptyTrashFragment dialog = new EmptyTrashFragment();
|
show(mParentFragment.getFragmentManager(), TAG_EMPTY_TRASH);
|
||||||
dialog.setTargetFragment(parent, 0 /* requestCode */);
|
|
||||||
dialog.show(parent.getFragmentManager(), TAG_EMPTY_TRASH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -48,10 +77,38 @@ public class EmptyTrashFragment extends InstrumentedDialogFragment {
|
|||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
return builder.setTitle(R.string.storage_trash_dialog_title)
|
return builder.setTitle(R.string.storage_trash_dialog_title)
|
||||||
.setMessage(R.string.storage_trash_dialog_ask_message)
|
.setMessage(getActivity().getString(R.string.storage_trash_dialog_ask_message,
|
||||||
.setPositiveButton(R.string.storage_trash_dialog_confirm, (dialog, which) -> {
|
StorageUtils.getStorageSizeLabel(getActivity(), mTrashSize)))
|
||||||
// TODO(170918505): Implement the logic in worker thread.
|
.setPositiveButton(R.string.storage_trash_dialog_confirm,
|
||||||
}).setNegativeButton(android.R.string.cancel, null)
|
(dialog, which) -> emptyTrashAsync())
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.create();
|
.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.os.storage.VolumeInfo;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
@@ -64,7 +65,8 @@ import java.util.Map;
|
|||||||
* categorization breakdown.
|
* categorization breakdown.
|
||||||
*/
|
*/
|
||||||
public class StorageItemPreferenceController extends AbstractPreferenceController implements
|
public class StorageItemPreferenceController extends AbstractPreferenceController implements
|
||||||
PreferenceControllerMixin {
|
PreferenceControllerMixin,
|
||||||
|
EmptyTrashFragment.OnEmptyTrashCompleteListener {
|
||||||
private static final String TAG = "StorageItemPreference";
|
private static final String TAG = "StorageItemPreference";
|
||||||
|
|
||||||
private static final String SYSTEM_FRAGMENT_TAG = "SystemInfo";
|
private static final String SYSTEM_FRAGMENT_TAG = "SystemInfo";
|
||||||
@@ -256,8 +258,7 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
|
|||||||
mGamesPreference.setVisible(privateStoragePreferencesVisible);
|
mGamesPreference.setVisible(privateStoragePreferencesVisible);
|
||||||
mDocumentsAndOtherPreference.setVisible(privateStoragePreferencesVisible);
|
mDocumentsAndOtherPreference.setVisible(privateStoragePreferencesVisible);
|
||||||
mSystemPreference.setVisible(privateStoragePreferencesVisible);
|
mSystemPreference.setVisible(privateStoragePreferencesVisible);
|
||||||
// TODO(b/170918505): Shows trash category after trash category feature complete.
|
mTrashPreference.setVisible(privateStoragePreferencesVisible);
|
||||||
mTrashPreference.setVisible(false);
|
|
||||||
|
|
||||||
if (privateStoragePreferencesVisible) {
|
if (privateStoragePreferencesVisible) {
|
||||||
final VolumeInfo sharedVolume = mSvp.findEmulatedForPrivate(mVolume);
|
final VolumeInfo sharedVolume = mSvp.findEmulatedForPrivate(mVolume);
|
||||||
@@ -460,13 +461,29 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
|
|||||||
private void launchTrashIntent() {
|
private void launchTrashIntent() {
|
||||||
final Intent intent = new Intent("android.settings.VIEW_TRASH");
|
final Intent intent = new Intent("android.settings.VIEW_TRASH");
|
||||||
|
|
||||||
if (intent.resolveActivity(mPackageManager) == null) {
|
if (mPackageManager.resolveActivityAsUser(intent, 0 /* flags */, mUserId) == null) {
|
||||||
EmptyTrashFragment.show(mFragment);
|
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 {
|
} else {
|
||||||
mContext.startActivityAsUser(intent, new UserHandle(mUserId));
|
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,
|
private static long totalValues(StorageMeasurement.MeasurementDetails details, int userId,
|
||||||
String... keys) {
|
String... keys) {
|
||||||
long total = 0;
|
long total = 0;
|
||||||
|
@@ -26,6 +26,8 @@ import android.os.storage.DiskInfo;
|
|||||||
import android.os.storage.StorageManager;
|
import android.os.storage.StorageManager;
|
||||||
import android.os.storage.VolumeInfo;
|
import android.os.storage.VolumeInfo;
|
||||||
import android.os.storage.VolumeRecord;
|
import android.os.storage.VolumeRecord;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.text.format.Formatter;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -115,6 +117,14 @@ public class StorageUtils {
|
|||||||
.launch();
|
.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. */
|
/** An AsyncTask to unmount a specified volume. */
|
||||||
public static class UnmountTask extends AsyncTask<Void, Void, Exception> {
|
public static class UnmountTask extends AsyncTask<Void, Void, Exception> {
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
Reference in New Issue
Block a user