am edb7b0d9: New storage dialogs.

* commit 'edb7b0d9a900a4a560d0777032600b52f38efd23':
  New storage dialogs.
This commit is contained in:
Jeff Sharkey
2015-06-15 04:20:55 +00:00
committed by Android Git Automerger
8 changed files with 236 additions and 39 deletions

View File

@@ -16,6 +16,12 @@
package com.android.settings.deviceinfo; package com.android.settings.deviceinfo;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.os.storage.StorageManager; import android.os.storage.StorageManager;
import android.os.storage.VolumeRecord; import android.os.storage.VolumeRecord;
@@ -32,6 +38,8 @@ import com.android.settings.InstrumentedFragment;
import com.android.settings.R; import com.android.settings.R;
public class PrivateVolumeForget extends InstrumentedFragment { public class PrivateVolumeForget extends InstrumentedFragment {
private static final String TAG_FORGET_CONFIRM = "forget_confirm";
private VolumeRecord mRecord; private VolumeRecord mRecord;
@Override @Override
@@ -60,9 +68,46 @@ public class PrivateVolumeForget extends InstrumentedFragment {
private final OnClickListener mConfirmListener = new OnClickListener() { private final OnClickListener mConfirmListener = new OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
final StorageManager storage = getActivity().getSystemService(StorageManager.class); ForgetConfirmFragment.show(PrivateVolumeForget.this, mRecord.getFsUuid());
storage.forgetVolume(mRecord.getFsUuid());
getActivity().finish();
} }
}; };
private static class ForgetConfirmFragment extends DialogFragment {
public static void show(Fragment parent, String fsUuid) {
final Bundle args = new Bundle();
args.putString(VolumeRecord.EXTRA_FS_UUID, fsUuid);
final ForgetConfirmFragment dialog = new ForgetConfirmFragment();
dialog.setArguments(args);
dialog.setTargetFragment(parent, 0);
dialog.show(parent.getFragmentManager(), TAG_FORGET_CONFIRM);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Context context = getActivity();
final StorageManager storage = context.getSystemService(StorageManager.class);
final String fsUuid = getArguments().getString(VolumeRecord.EXTRA_FS_UUID);
final VolumeRecord record = storage.findRecordByUuid(fsUuid);
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(TextUtils.expandTemplate(
getText(R.string.storage_internal_forget_confirm_title), record.getNickname()));
builder.setMessage(TextUtils.expandTemplate(
getText(R.string.storage_internal_forget_confirm), record.getNickname()));
builder.setPositiveButton(R.string.storage_menu_forget,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
storage.forgetVolume(fsUuid);
getActivity().finish();
}
});
builder.setNegativeButton(R.string.cancel, null);
return builder.create();
}
}
} }

View File

@@ -173,6 +173,8 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
screen.removeAll(); screen.removeAll();
if (!mVolume.isMountedReadable()) { if (!mVolume.isMountedReadable()) {
Log.d(TAG, "Leaving details fragment due to state " + mVolume.getState());
finish();
return; return;
} }
@@ -288,6 +290,8 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
format.setVisible(true); format.setVisible(true);
} }
format.setTitle(R.string.storage_menu_format_public);
// Only offer to migrate when not current storage // Only offer to migrate when not current storage
final VolumeInfo privateVol = getActivity().getPackageManager() final VolumeInfo privateVol = getActivity().getPackageManager()
.getPrimaryStorageCurrentVolume(); .getPrimaryStorageCurrentVolume();

View File

@@ -16,6 +16,8 @@
package com.android.settings.deviceinfo; package com.android.settings.deviceinfo;
import static com.android.settings.deviceinfo.StorageSettings.TAG;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
@@ -29,6 +31,7 @@ import android.preference.Preference;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.provider.DocumentsContract; import android.provider.DocumentsContract;
import android.text.format.Formatter; import android.text.format.Formatter;
import android.util.Log;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
@@ -61,8 +64,8 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
private Preference mMount; private Preference mMount;
private Preference mUnmount; private Preference mUnmount;
private Preference mFormat; private Preference mFormatPublic;
private Preference mFormatInternal; private Preference mFormatPrivate;
private long mTotalSize; private long mTotalSize;
private long mAvailSize; private long mAvailSize;
@@ -106,8 +109,8 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
mMount = buildAction(R.string.storage_menu_mount); mMount = buildAction(R.string.storage_menu_mount);
mUnmount = buildAction(R.string.storage_menu_unmount); mUnmount = buildAction(R.string.storage_menu_unmount);
mFormat = buildAction(R.string.storage_menu_format); mFormatPublic = buildAction(R.string.storage_menu_format);
mFormatInternal = buildAction(R.string.storage_menu_format_private); mFormatPrivate = buildAction(R.string.storage_menu_format_private);
} }
public void update() { public void update() {
@@ -118,6 +121,12 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
screen.removeAll(); screen.removeAll();
if (!mVolume.isMountedReadable()) {
Log.d(TAG, "Leaving details fragment due to state " + mVolume.getState());
finish();
return;
}
if (mVolume.isMountedReadable()) { if (mVolume.isMountedReadable()) {
screen.addPreference(mGraph); screen.addPreference(mGraph);
screen.addPreference(mTotal); screen.addPreference(mTotal);
@@ -142,9 +151,9 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
if (mVolume.isMountedReadable()) { if (mVolume.isMountedReadable()) {
screen.addPreference(mUnmount); screen.addPreference(mUnmount);
} }
screen.addPreference(mFormat); screen.addPreference(mFormatPublic);
if (mDisk.isAdoptable()) { if (mDisk.isAdoptable()) {
screen.addPreference(mFormatInternal); screen.addPreference(mFormatPrivate);
} }
} }
@@ -196,12 +205,12 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
new MountTask(context, mVolume).execute(); new MountTask(context, mVolume).execute();
} else if (pref == mUnmount) { } else if (pref == mUnmount) {
new UnmountTask(context, mVolume).execute(); new UnmountTask(context, mVolume).execute();
} else if (pref == mFormat) { } else if (pref == mFormatPublic) {
final Intent intent = new Intent(context, StorageWizardFormatConfirm.class); final Intent intent = new Intent(context, StorageWizardFormatConfirm.class);
intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId()); intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false); intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false);
startActivity(intent); startActivity(intent);
} else if (pref == mFormatInternal) { } else if (pref == mFormatPrivate) {
final Intent intent = new Intent(context, StorageWizardFormatConfirm.class); final Intent intent = new Intent(context, StorageWizardFormatConfirm.class);
intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId()); intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, true); intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, true);

View File

@@ -16,20 +16,26 @@
package com.android.settings.deviceinfo; package com.android.settings.deviceinfo;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserManager; import android.os.UserManager;
import android.os.storage.DiskInfo;
import android.os.storage.StorageEventListener; import android.os.storage.StorageEventListener;
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.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceCategory; import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast; import android.widget.Toast;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
@@ -50,8 +56,10 @@ import java.util.List;
public class StorageSettings extends SettingsPreferenceFragment implements Indexable { public class StorageSettings extends SettingsPreferenceFragment implements Indexable {
static final String TAG = "StorageSettings"; static final String TAG = "StorageSettings";
private static final String TAG_VOLUME_UNMOUNTED = "volume_unmounted";
private static final String TAG_DISK_INIT = "disk_init";
// TODO: badging to indicate devices running low on storage // TODO: badging to indicate devices running low on storage
// TODO: show currently ejected private volumes
private UserManager mUserManager; private UserManager mUserManager;
private StorageManager mStorageManager; private StorageManager mStorageManager;
@@ -127,6 +135,33 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
} }
} }
// Show missing private volumes
final List<VolumeRecord> recs = mStorageManager.getVolumeRecords();
for (VolumeRecord rec : recs) {
if (rec.getType() == VolumeInfo.TYPE_PRIVATE
&& mStorageManager.findVolumeByUuid(rec.getFsUuid()) == null) {
final Preference pref = new Preference(context);
pref.setKey(rec.getFsUuid());
pref.setTitle(rec.getNickname());
pref.setSummary(com.android.internal.R.string.ext_media_status_missing);
pref.setIcon(R.drawable.ic_settings_storage);
mInternalCategory.addPreference(pref);
}
}
// Show unsupported disks to give a chance to init
final List<DiskInfo> disks = mStorageManager.getDisks();
for (DiskInfo disk : disks) {
if (disk.volumeCount == 0 && disk.size > 0) {
final Preference pref = new Preference(context);
pref.setKey(disk.getId());
pref.setTitle(disk.getDescription());
pref.setSummary(com.android.internal.R.string.ext_media_status_unsupported);
pref.setIcon(R.drawable.ic_sim_sd);
mExternalCategory.addPreference(pref);
}
}
if (mInternalCategory.getPreferenceCount() > 0) { if (mInternalCategory.getPreferenceCount() > 0) {
getPreferenceScreen().addPreference(mInternalCategory); getPreferenceScreen().addPreference(mInternalCategory);
} }
@@ -150,14 +185,22 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
@Override @Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference pref) { public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference pref) {
final String volId = pref.getKey(); final String key = pref.getKey();
final VolumeInfo vol = mStorageManager.findVolumeById(volId); if (pref instanceof StorageVolumePreference) {
if (vol == null) { // Picked a normal volume
return false; final VolumeInfo vol = mStorageManager.findVolumeById(key);
} else if (vol.getType() == VolumeInfo.TYPE_PRIVATE) { if (vol.getState() == VolumeInfo.STATE_UNMOUNTED) {
VolumeUnmountedFragment.show(this, vol.getId());
return true;
} else if (vol.getState() == VolumeInfo.STATE_UNMOUNTABLE) {
DiskInitFragment.show(this, R.string.storage_dialog_unmountable, vol.getDiskId());
return true;
}
if (vol.getType() == VolumeInfo.TYPE_PRIVATE) {
final Bundle args = new Bundle(); final Bundle args = new Bundle();
args.putString(VolumeInfo.EXTRA_VOLUME_ID, volId); args.putString(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
startFragment(this, PrivateVolumeSettings.class.getCanonicalName(), startFragment(this, PrivateVolumeSettings.class.getCanonicalName(),
-1, 0, args); -1, 0, args);
return true; return true;
@@ -168,13 +211,27 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
return true; return true;
} else { } else {
final Bundle args = new Bundle(); final Bundle args = new Bundle();
args.putString(VolumeInfo.EXTRA_VOLUME_ID, volId); args.putString(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
startFragment(this, PublicVolumeSettings.class.getCanonicalName(), startFragment(this, PublicVolumeSettings.class.getCanonicalName(),
-1, 0, args); -1, 0, args);
return true; return true;
} }
} }
} else if (key.startsWith("disk:")) {
// Picked an unsupported disk
DiskInitFragment.show(this, R.string.storage_dialog_unsupported, key);
return true;
} else {
// Picked a missing private volume
final Bundle args = new Bundle();
args.putString(VolumeRecord.EXTRA_FS_UUID, key);
startFragment(this, PrivateVolumeForget.class.getCanonicalName(),
R.string.storage_menu_forget, 0, args);
return true;
}
return false; return false;
} }
@@ -250,6 +307,81 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
} }
} }
private static class VolumeUnmountedFragment extends DialogFragment {
public static void show(Fragment parent, String volumeId) {
final Bundle args = new Bundle();
args.putString(VolumeInfo.EXTRA_VOLUME_ID, volumeId);
final VolumeUnmountedFragment dialog = new VolumeUnmountedFragment();
dialog.setArguments(args);
dialog.setTargetFragment(parent, 0);
dialog.show(parent.getFragmentManager(), TAG_VOLUME_UNMOUNTED);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Context context = getActivity();
final StorageManager sm = context.getSystemService(StorageManager.class);
final String volumeId = getArguments().getString(VolumeInfo.EXTRA_VOLUME_ID);
final VolumeInfo vol = sm.findVolumeById(volumeId);
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(TextUtils.expandTemplate(
getText(R.string.storage_dialog_unmounted), vol.getDisk().getDescription()));
builder.setPositiveButton(R.string.storage_menu_mount,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new MountTask(context, vol).execute();
}
});
builder.setNegativeButton(R.string.cancel, null);
return builder.create();
}
}
private static class DiskInitFragment extends DialogFragment {
public static void show(Fragment parent, int resId, String diskId) {
final Bundle args = new Bundle();
args.putInt(Intent.EXTRA_TEXT, resId);
args.putString(DiskInfo.EXTRA_DISK_ID, diskId);
final DiskInitFragment dialog = new DiskInitFragment();
dialog.setArguments(args);
dialog.setTargetFragment(parent, 0);
dialog.show(parent.getFragmentManager(), TAG_DISK_INIT);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Context context = getActivity();
final StorageManager sm = context.getSystemService(StorageManager.class);
final int resId = getArguments().getInt(Intent.EXTRA_TEXT);
final String diskId = getArguments().getString(DiskInfo.EXTRA_DISK_ID);
final DiskInfo disk = sm.findDiskById(diskId);
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(TextUtils.expandTemplate(getText(resId), disk.getDescription()));
builder.setPositiveButton(R.string.storage_menu_set_up,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final Intent intent = new Intent(context, StorageWizardInit.class);
intent.putExtra(DiskInfo.EXTRA_DISK_ID, diskId);
startActivity(intent);
}
});
builder.setNegativeButton(R.string.cancel, null);
return builder.create();
}
}
/** /**
* Enable indexing of searchable data * Enable indexing of searchable data
*/ */

View File

@@ -50,9 +50,12 @@ public class StorageVolumePreference extends Preference {
if (volume.isMountedReadable()) { if (volume.isMountedReadable()) {
// TODO: move statfs() to background thread // TODO: move statfs() to background thread
final File path = volume.getPath(); final File path = volume.getPath();
final String free = Formatter.formatFileSize(context, path.getFreeSpace()); final long usedBytes = path.getTotalSpace() - path.getFreeSpace();
final String used = Formatter.formatFileSize(context, usedBytes);
final String total = Formatter.formatFileSize(context, path.getTotalSpace()); final String total = Formatter.formatFileSize(context, path.getTotalSpace());
setSummary(context.getString(R.string.storage_volume_summary, free, total)); setSummary(context.getString(R.string.storage_volume_summary, used, total));
} else {
setSummary(volume.getStateDescription());
} }
// TODO: better icons // TODO: better icons

View File

@@ -20,7 +20,6 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.storage.DiskInfo; import android.os.storage.DiskInfo;
import com.android.internal.util.Preconditions;
import com.android.settings.R; import com.android.settings.R;
public class StorageWizardFormatConfirm extends StorageWizardBase { public class StorageWizardFormatConfirm extends StorageWizardBase {

View File

@@ -33,7 +33,6 @@ import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
import com.android.internal.util.Preconditions;
import com.android.settings.R; import com.android.settings.R;
public class StorageWizardFormatProgress extends StorageWizardBase { public class StorageWizardFormatProgress extends StorageWizardBase {

View File

@@ -24,7 +24,6 @@ import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RadioButton; import android.widget.RadioButton;
import com.android.internal.util.Preconditions;
import com.android.settings.R; import com.android.settings.R;
public class StorageWizardInit extends StorageWizardBase { public class StorageWizardInit extends StorageWizardBase {
@@ -56,6 +55,13 @@ public class StorageWizardInit extends StorageWizardBase {
mRadioExternal.getCompoundPaddingRight(), 0); mRadioExternal.getCompoundPaddingRight(), 0);
getNextButton().setEnabled(false); getNextButton().setEnabled(false);
if (!mDisk.isAdoptable()) {
// If not adoptable, we only have one choice
mRadioExternal.setChecked(true);
onNavigateNext();
finish();
}
} }
private final OnCheckedChangeListener mRadioListener = new OnCheckedChangeListener() { private final OnCheckedChangeListener mRadioListener = new OnCheckedChangeListener() {