Merge "More storage UI updates." into mnc-dev

This commit is contained in:
Jeff Sharkey
2015-06-16 04:47:16 +00:00
committed by Android (Google) Code Review
17 changed files with 576 additions and 280 deletions

View File

@@ -19,11 +19,12 @@ import android.content.Context;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.text.format.Formatter.BytesResult;
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
import com.android.settings.InstrumentedFragment;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.applications.ProcStatsData.MemInfo;
@@ -76,7 +77,8 @@ public class ProcessStatsSummary extends ProcessStatsBase implements OnPreferenc
double usedRam = memInfo.realUsedRam;
double totalRam = memInfo.realTotalRam;
double freeRam = memInfo.realFreeRam;
String usedString = Formatter.formatShortFileSize(context, (long) usedRam);
BytesResult usedResult = Formatter.formatBytes(context.getResources(), (long) usedRam,
Formatter.FLAG_SHORTER);
String totalString = Formatter.formatShortFileSize(context, (long) totalRam);
String freeString = Formatter.formatShortFileSize(context, (long) freeRam);
CharSequence memString;
@@ -87,7 +89,8 @@ public class ProcessStatsSummary extends ProcessStatsBase implements OnPreferenc
} else {
memString = memStatesStr[memStatesStr.length - 1];
}
mMemStatus.setText(usedString);
mMemStatus.setText(TextUtils.expandTemplate(getText(R.string.storage_size_large),
usedResult.value, usedResult.units));
float usedRatio = (float)(usedRam / (freeRam + usedRam));
mColors.setRatios(usedRatio, 0, 1 - usedRatio);

View File

@@ -21,7 +21,7 @@ import static com.android.settings.deviceinfo.StorageSettings.TAG;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.DownloadManager;
import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
@@ -34,15 +34,16 @@ import android.os.Bundle;
import android.os.Environment;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.DiskInfo;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.os.storage.VolumeRecord;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.provider.MediaStore;
import android.provider.DocumentsContract;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.text.format.Formatter.BytesResult;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -79,8 +80,12 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
// TODO: warn when mounted read-only
private static final String TAG_RENAME = "rename";
private static final String TAG_OTHER_INFO = "otherInfo";
private static final String TAG_USER_INFO = "userInfo";
private static final String TAG_CONFIRM_CLEAR_CACHE = "confirmClearCache";
private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents";
private StorageManager mStorageManager;
private UserManager mUserManager;
@@ -94,19 +99,16 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
private int mNextOrder = 0;
private UsageBarPreference mGraph;
private StorageItemPreference mTotal;
private StorageItemPreference mAvailable;
private StorageSummaryPreference mSummary;
private StorageItemPreference mApps;
private StorageItemPreference mDcim;
private StorageItemPreference mMusic;
private StorageItemPreference mDownloads;
private StorageItemPreference mImages;
private StorageItemPreference mVideos;
private StorageItemPreference mAudio;
private StorageItemPreference mOther;
private StorageItemPreference mCache;
private StorageItemPreference mMisc;
private List<StorageItemPreference> mUsers = Lists.newArrayList();
private long mTotalSize;
private long mAvailSize;
private Preference mExplore;
@Override
protected int getMetricsCategory() {
@@ -136,28 +138,26 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
mMeasure = new StorageMeasurement(context, mVolume, mSharedVolume);
mMeasure.setReceiver(mReceiver);
mGraph = buildGraph();
mTotal = buildItem(R.string.memory_size, 0);
mAvailable = buildItem(R.string.memory_available, R.color.memory_avail);
mSummary = new StorageSummaryPreference(context);
mApps = buildItem(R.string.memory_apps_usage, R.color.memory_apps_usage);
mDcim = buildItem(R.string.memory_dcim_usage, R.color.memory_dcim);
mMusic = buildItem(R.string.memory_music_usage, R.color.memory_music);
mDownloads = buildItem(R.string.memory_downloads_usage, R.color.memory_downloads);
mCache = buildItem(R.string.memory_media_cache_usage, R.color.memory_cache);
mMisc = buildItem(R.string.memory_media_misc_usage, R.color.memory_misc);
mApps = buildItem(R.string.storage_detail_apps);
mImages = buildItem(R.string.storage_detail_images);
mVideos = buildItem(R.string.storage_detail_videos);
mAudio = buildItem(R.string.storage_detail_audio);
mOther = buildItem(R.string.storage_detail_other);
mCache = buildItem(R.string.storage_detail_cached);
mCurrentUser = mUserManager.getUserInfo(UserHandle.myUserId());
final List<UserInfo> otherUsers = getUsersExcluding(mCurrentUser);
for (int i = 0; i < otherUsers.size(); i++) {
final UserInfo user = otherUsers.get(i);
final int colorRes = i % 2 == 0 ? R.color.memory_user_light
: R.color.memory_user_dark;
final StorageItemPreference userPref = new StorageItemPreference(
context, user.name, colorRes, user.id);
context, user.name, user.id);
mUsers.add(userPref);
}
mExplore = buildAction(R.string.storage_menu_explore);
setHasOptionsMenu(true);
}
@@ -178,22 +178,25 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
return;
}
screen.addPreference(mGraph);
screen.addPreference(mTotal);
screen.addPreference(mAvailable);
screen.addPreference(mSummary);
final boolean showUsers = !mUsers.isEmpty();
final boolean showShared = (mSharedVolume != null) && mSharedVolume.isMountedReadable();
if (showUsers) {
screen.addPreference(new PreferenceHeader(context, mCurrentUser.name));
}
screen.addPreference(mApps);
screen.addPreference(mDcim);
screen.addPreference(mMusic);
screen.addPreference(mDownloads);
if (showShared) {
screen.addPreference(mImages);
screen.addPreference(mVideos);
screen.addPreference(mAudio);
screen.addPreference(mOther);
}
screen.addPreference(mCache);
screen.addPreference(mMisc);
if (showShared) {
screen.addPreference(mExplore);
}
if (showUsers) {
screen.addPreference(new PreferenceHeader(context, R.string.storage_other_users));
for (Preference pref : mUsers) {
@@ -209,29 +212,29 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
}
final File file = mVolume.getPath();
mTotalSize = file.getTotalSpace();
mAvailSize = file.getFreeSpace();
final long totalBytes = file.getTotalSpace();
final long freeBytes = file.getFreeSpace();
final long usedBytes = totalBytes - freeBytes;
mTotal.setSummary(Formatter.formatFileSize(context, mTotalSize));
mAvailable.setSummary(Formatter.formatFileSize(context, mAvailSize));
mGraph.clear();
mGraph.addEntry(0, (mTotalSize - mAvailSize) / (float) mTotalSize,
android.graphics.Color.GRAY);
mGraph.commit();
final BytesResult result = Formatter.formatBytes(getResources(), usedBytes, 0);
mSummary.setTitle(TextUtils.expandTemplate(getText(R.string.storage_size_large),
result.value, result.units));
mSummary.setSummary(getString(R.string.storage_volume_used,
Formatter.formatFileSize(context, totalBytes)));
mSummary.setPercent((int) ((usedBytes * 100) / totalBytes));
mMeasure.forceMeasure();
}
private UsageBarPreference buildGraph() {
final UsageBarPreference pref = new UsageBarPreference(getActivity());
private StorageItemPreference buildItem(int titleRes) {
final StorageItemPreference pref = new StorageItemPreference(getActivity(), titleRes);
pref.setOrder(mNextOrder++);
return pref;
}
private StorageItemPreference buildItem(int titleRes, int colorRes) {
final StorageItemPreference pref = new StorageItemPreference(getActivity(), titleRes,
colorRes);
private Preference buildAction(int titleRes) {
final Preference pref = new Preference(getActivity());
pref.setTitle(titleRes);
pref.setOrder(mNextOrder++);
return pref;
}
@@ -341,27 +344,40 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
intent = Utils.onBuildStartFragmentIntent(getActivity(),
ManageApplications.class.getName(), args, null, R.string.apps_storage, null,
false);
} else if (pref == mDownloads) {
intent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS).putExtra(
DownloadManager.INTENT_EXTRAS_SORT_BY_SIZE, true);
} else if (pref == mMusic) {
intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("audio/mp3");
} else if (pref == mImages) {
intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "images_root"));
intent.addCategory(Intent.CATEGORY_DEFAULT);
} else if (pref == mDcim) {
intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
} else if (pref == mVideos) {
intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "videos_root"));
intent.addCategory(Intent.CATEGORY_DEFAULT);
} else if (pref == mAudio) {
intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root"));
intent.addCategory(Intent.CATEGORY_DEFAULT);
} else if (pref == mOther) {
OtherInfoFragment.show(this, mStorageManager.getBestVolumeDescription(mVolume),
mSharedVolume);
return true;
} else if (pref == mCache) {
ConfirmClearCacheFragment.show(this);
return true;
} else if (pref == mMisc) {
} else if (pref == mExplore) {
intent = mSharedVolume.buildBrowseIntent();
}
if (mUsers.contains(pref)) {
UserInfoFragment.show(this, pref.getTitle(), pref.getSummary());
return true;
}
if (intent != null) {
try {
startActivity(intent);
@@ -381,39 +397,31 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
};
private void updateDetails(MeasurementDetails details) {
mGraph.clear();
updatePreference(mApps, details.appsSize);
final long dcimSize = totalValues(details.mediaSize, Environment.DIRECTORY_DCIM,
final long imagesSize = totalValues(details.mediaSize, Environment.DIRECTORY_DCIM,
Environment.DIRECTORY_MOVIES, Environment.DIRECTORY_PICTURES);
updatePreference(mDcim, dcimSize);
updatePreference(mImages, imagesSize);
final long musicSize = totalValues(details.mediaSize, Environment.DIRECTORY_MUSIC,
final long videosSize = totalValues(details.mediaSize, Environment.DIRECTORY_MOVIES);
updatePreference(mVideos, videosSize);
final long audioSize = totalValues(details.mediaSize, Environment.DIRECTORY_MUSIC,
Environment.DIRECTORY_ALARMS, Environment.DIRECTORY_NOTIFICATIONS,
Environment.DIRECTORY_RINGTONES, Environment.DIRECTORY_PODCASTS);
updatePreference(mMusic, musicSize);
final long downloadsSize = totalValues(details.mediaSize, Environment.DIRECTORY_DOWNLOADS);
updatePreference(mDownloads, downloadsSize);
updatePreference(mAudio, audioSize);
updatePreference(mCache, details.cacheSize);
updatePreference(mMisc, details.miscSize);
updatePreference(mOther, details.miscSize);
for (StorageItemPreference userPref : mUsers) {
final long userSize = details.usersSize.get(userPref.userHandle);
updatePreference(userPref, userSize);
}
mGraph.commit();
}
private void updatePreference(StorageItemPreference pref, long size) {
pref.setSummary(Formatter.formatFileSize(getActivity(), size));
if (size > 0) {
final int order = pref.getOrder();
mGraph.addEntry(order, size / (float) mTotalSize, pref.color);
}
}
/**
@@ -507,11 +515,78 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
}
}
public static class OtherInfoFragment extends DialogFragment {
public static void show(Fragment parent, String title, VolumeInfo sharedVol) {
if (!parent.isAdded()) return;
final OtherInfoFragment dialog = new OtherInfoFragment();
dialog.setTargetFragment(parent, 0);
final Bundle args = new Bundle();
args.putString(Intent.EXTRA_TITLE, title);
args.putParcelable(Intent.EXTRA_INTENT, sharedVol.buildBrowseIntent());
dialog.setArguments(args);
dialog.show(parent.getFragmentManager(), TAG_OTHER_INFO);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Context context = getActivity();
final String title = getArguments().getString(Intent.EXTRA_TITLE);
final Intent intent = getArguments().getParcelable(Intent.EXTRA_INTENT);
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(
TextUtils.expandTemplate(getText(R.string.storage_detail_dialog_other), title));
builder.setPositiveButton(R.string.storage_menu_explore,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(intent);
}
});
builder.setNegativeButton(android.R.string.cancel, null);
return builder.create();
}
}
public static class UserInfoFragment extends DialogFragment {
public static void show(Fragment parent, CharSequence userLabel, CharSequence userSize) {
if (!parent.isAdded()) return;
final UserInfoFragment dialog = new UserInfoFragment();
dialog.setTargetFragment(parent, 0);
final Bundle args = new Bundle();
args.putCharSequence(Intent.EXTRA_TITLE, userLabel);
args.putCharSequence(Intent.EXTRA_SUBJECT, userSize);
dialog.setArguments(args);
dialog.show(parent.getFragmentManager(), TAG_USER_INFO);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Context context = getActivity();
final CharSequence userLabel = getArguments().getCharSequence(Intent.EXTRA_TITLE);
final CharSequence userSize = getArguments().getCharSequence(Intent.EXTRA_SUBJECT);
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(TextUtils.expandTemplate(
getText(R.string.storage_detail_dialog_user), userLabel, userSize));
builder.setPositiveButton(android.R.string.ok, null);
return builder.create();
}
}
/**
* Dialog to request user confirmation before clearing all cache data.
*/
public static class ConfirmClearCacheFragment extends DialogFragment {
public static void show(PrivateVolumeSettings parent) {
public static void show(Fragment parent) {
if (!parent.isAdded()) return;
final ConfirmClearCacheFragment dialog = new ConfirmClearCacheFragment();

View File

@@ -30,7 +30,9 @@ import android.os.storage.VolumeRecord;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.provider.DocumentsContract;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.text.format.Formatter.BytesResult;
import android.util.Log;
import com.android.internal.logging.MetricsLogger;
@@ -58,18 +60,13 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
private int mNextOrder = 0;
private UsageBarPreference mGraph;
private StorageItemPreference mTotal;
private StorageItemPreference mAvailable;
private StorageSummaryPreference mSummary;
private Preference mMount;
private Preference mUnmount;
private Preference mFormatPublic;
private Preference mFormatPrivate;
private long mTotalSize;
private long mAvailSize;
@Override
protected int getMetricsCategory() {
return MetricsLogger.DEVICEINFO_STORAGE;
@@ -103,9 +100,7 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
addPreferencesFromResource(R.xml.device_info_storage_volume);
mGraph = buildGraph();
mTotal = buildItem(R.string.memory_size, 0);
mAvailable = buildItem(R.string.memory_available, R.color.memory_avail);
mSummary = new StorageSummaryPreference(context);
mMount = buildAction(R.string.storage_menu_mount);
mUnmount = buildAction(R.string.storage_menu_unmount);
@@ -128,21 +123,19 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
}
if (mVolume.isMountedReadable()) {
screen.addPreference(mGraph);
screen.addPreference(mTotal);
screen.addPreference(mAvailable);
screen.addPreference(mSummary);
final File file = mVolume.getPath();
mTotalSize = file.getTotalSpace();
mAvailSize = file.getFreeSpace();
final long totalBytes = file.getTotalSpace();
final long freeBytes = file.getFreeSpace();
final long usedBytes = totalBytes - freeBytes;
mTotal.setSummary(Formatter.formatFileSize(context, mTotalSize));
mAvailable.setSummary(Formatter.formatFileSize(context, mAvailSize));
mGraph.clear();
mGraph.addEntry(0, (mTotalSize - mAvailSize) / (float) mTotalSize,
android.graphics.Color.GRAY);
mGraph.commit();
final BytesResult result = Formatter.formatBytes(getResources(), usedBytes, 0);
mSummary.setTitle(TextUtils.expandTemplate(getText(R.string.storage_size_large),
result.value, result.units));
mSummary.setSummary(getString(R.string.storage_volume_used,
Formatter.formatFileSize(context, totalBytes)));
mSummary.setPercent((int) ((usedBytes * 100) / totalBytes));
}
if (mVolume.getState() == VolumeInfo.STATE_UNMOUNTED) {
@@ -157,19 +150,6 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
}
}
private UsageBarPreference buildGraph() {
final UsageBarPreference pref = new UsageBarPreference(getActivity());
pref.setOrder(mNextOrder++);
return pref;
}
private StorageItemPreference buildItem(int titleRes, int colorRes) {
final StorageItemPreference pref = new StorageItemPreference(getActivity(), titleRes,
colorRes);
pref.setOrder(mNextOrder++);
return pref;
}
private Preference buildAction(int titleRes) {
final Preference pref = new Preference(getActivity());
pref.setTitle(titleRes);

View File

@@ -17,52 +17,27 @@
package com.android.settings.deviceinfo;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.os.UserHandle;
import android.preference.Preference;
import com.android.settings.R;
public class StorageItemPreference extends Preference {
public final int color;
public final int userHandle;
public StorageItemPreference(Context context, int titleRes, int colorRes) {
this(context, context.getText(titleRes), colorRes, UserHandle.USER_NULL);
public StorageItemPreference(Context context, int titleRes) {
this(context, context.getText(titleRes), UserHandle.USER_NULL);
}
public StorageItemPreference(
Context context, CharSequence title, int colorRes, int userHandle) {
public StorageItemPreference(Context context, CharSequence title, int userHandle) {
super(context);
if (colorRes != 0) {
this.color = context.getColor(colorRes);
final Resources res = context.getResources();
final int width = res.getDimensionPixelSize(R.dimen.device_memory_usage_button_width);
final int height = res.getDimensionPixelSize(R.dimen.device_memory_usage_button_height);
setIcon(createRectShape(width, height, this.color));
} else {
this.color = Color.MAGENTA;
}
setTitle(title);
setSummary(R.string.memory_calculating_size);
this.userHandle = userHandle;
}
private static ShapeDrawable createRectShape(int width, int height, int color) {
ShapeDrawable shape = new ShapeDrawable(new RectShape());
shape.setIntrinsicHeight(height);
shape.setIntrinsicWidth(width);
shape.getPaint().setColor(color);
return shape;
}
public void setLoading() {
setSummary(R.string.memory_calculating_size);
}

View File

@@ -23,9 +23,9 @@ import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.UserManager;
import android.os.storage.DiskInfo;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
@@ -35,6 +35,8 @@ import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.text.format.Formatter.BytesResult;
import android.util.Log;
import android.widget.Toast;
@@ -45,6 +47,7 @@ import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -59,14 +62,24 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
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
static final int COLOR_PUBLIC = Color.parseColor("#ff9e9e9e");
static final int COLOR_WARNING = Color.parseColor("#fff4511e");
static final int[] COLOR_PRIVATE = new int[] {
Color.parseColor("#ff26a69a"),
Color.parseColor("#ffab47bc"),
Color.parseColor("#fff2a600"),
Color.parseColor("#ffec407a"),
Color.parseColor("#ffc0ca33"),
};
private UserManager mUserManager;
private StorageManager mStorageManager;
private PreferenceCategory mInternalCategory;
private PreferenceCategory mExternalCategory;
private StorageSummaryPreference mInternalSummary;
@Override
protected int getMetricsCategory() {
return MetricsLogger.DEVICEINFO_STORAGE;
@@ -83,8 +96,6 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
final Context context = getActivity();
mUserManager = context.getSystemService(UserManager.class);
mStorageManager = context.getSystemService(StorageManager.class);
mStorageManager.registerListener(mStorageListener);
@@ -93,7 +104,7 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
mInternalCategory = (PreferenceCategory) findPreference("storage_internal");
mExternalCategory = (PreferenceCategory) findPreference("storage_external");
// TODO: if only one volume visible, shortcut into it
mInternalSummary = new StorageSummaryPreference(context);
setHasOptionsMenu(true);
}
@@ -124,14 +135,28 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
mInternalCategory.removeAll();
mExternalCategory.removeAll();
mInternalCategory.addPreference(mInternalSummary);
int privateCount = 0;
long privateUsedBytes = 0;
long privateTotalBytes = 0;
final List<VolumeInfo> volumes = mStorageManager.getVolumes();
Collections.sort(volumes, VolumeInfo.getDescriptionComparator());
for (VolumeInfo vol : volumes) {
if (vol.getType() == VolumeInfo.TYPE_PRIVATE) {
mInternalCategory.addPreference(new StorageVolumePreference(context, vol));
final int color = COLOR_PRIVATE[privateCount++ % COLOR_PRIVATE.length];
mInternalCategory.addPreference(
new StorageVolumePreference(context, vol, color));
if (vol.isMountedReadable()) {
final File path = vol.getPath();
privateUsedBytes += path.getTotalSpace() - path.getFreeSpace();
privateTotalBytes += path.getTotalSpace();
}
} else if (vol.getType() == VolumeInfo.TYPE_PUBLIC) {
mExternalCategory.addPreference(new StorageVolumePreference(context, vol));
mExternalCategory.addPreference(
new StorageVolumePreference(context, vol, COLOR_PUBLIC));
}
}
@@ -162,12 +187,28 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
}
}
final BytesResult result = Formatter.formatBytes(getResources(), privateUsedBytes, 0);
mInternalSummary.setTitle(TextUtils.expandTemplate(getText(R.string.storage_size_large),
result.value, result.units));
mInternalSummary.setSummary(getString(R.string.storage_volume_used_total,
Formatter.formatFileSize(context, privateTotalBytes)));
if (mInternalCategory.getPreferenceCount() > 0) {
getPreferenceScreen().addPreference(mInternalCategory);
}
if (mExternalCategory.getPreferenceCount() > 0) {
getPreferenceScreen().addPreference(mExternalCategory);
}
if (mInternalCategory.getPreferenceCount() == 2
&& mExternalCategory.getPreferenceCount() == 0) {
// Only showing primary internal storage, so just shortcut
final Bundle args = new Bundle();
args.putString(VolumeInfo.EXTRA_VOLUME_ID, VolumeInfo.ID_PRIVATE_INTERNAL);
startFragment(this, PrivateVolumeSettings.class.getCanonicalName(),
-1, 0, args);
finish();
}
}
@Override

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.deviceinfo;
import android.content.Context;
import android.preference.Preference;
import android.view.View;
import android.widget.ProgressBar;
import com.android.settings.R;
public class StorageSummaryPreference extends Preference {
private int mPercent = -1;
public StorageSummaryPreference(Context context) {
super(context);
setLayoutResource(R.layout.storage_summary);
setEnabled(false);
}
public void setPercent(int percent) {
mPercent = percent;
}
@Override
protected void onBindView(View view) {
final ProgressBar progress = (ProgressBar) view.findViewById(android.R.id.progress);
if (mPercent != -1) {
progress.setVisibility(View.VISIBLE);
progress.setProgress(mPercent);
} else {
progress.setVisibility(View.GONE);
}
super.onBindView(view);
}
}

View File

@@ -17,12 +17,17 @@
package com.android.settings.deviceinfo;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.preference.Preference;
import android.text.format.Formatter;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.android.settings.R;
@@ -38,32 +43,53 @@ public class StorageVolumePreference extends Preference {
private final StorageManager mStorageManager;
private final VolumeInfo mVolume;
public StorageVolumePreference(Context context, VolumeInfo volume) {
private int mColor;
private int mUsedPercent = -1;
public StorageVolumePreference(Context context, VolumeInfo volume, int color) {
super(context);
mStorageManager = context.getSystemService(StorageManager.class);
mVolume = volume;
mColor = color;
setLayoutResource(R.layout.storage_volume);
setKey(volume.getId());
setTitle(mStorageManager.getBestVolumeDescription(volume));
Drawable icon;
if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(volume.getId())) {
icon = context.getDrawable(R.drawable.ic_settings_storage);
} else {
icon = context.getDrawable(R.drawable.ic_sim_sd);
}
if (volume.isMountedReadable()) {
// TODO: move statfs() to background thread
final File path = volume.getPath();
final long usedBytes = path.getTotalSpace() - path.getFreeSpace();
final long freeBytes = path.getFreeSpace();
final long totalBytes = path.getTotalSpace();
final long usedBytes = totalBytes - freeBytes;
final String used = Formatter.formatFileSize(context, usedBytes);
final String total = Formatter.formatFileSize(context, path.getTotalSpace());
final String total = Formatter.formatFileSize(context, totalBytes);
setSummary(context.getString(R.string.storage_volume_summary, used, total));
mUsedPercent = (int) ((usedBytes * 100) / totalBytes);
if (freeBytes < mStorageManager.getStorageLowBytes(path)) {
mColor = StorageSettings.COLOR_WARNING;
icon = context.getDrawable(R.drawable.ic_warning_24dp);
}
} else {
setSummary(volume.getStateDescription());
mUsedPercent = -1;
}
// TODO: better icons
if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(volume.getId())) {
setIcon(context.getDrawable(R.drawable.ic_settings_storage));
} else {
setIcon(context.getDrawable(R.drawable.ic_sim_sd));
}
icon.mutate();
icon.setTint(mColor);
setIcon(icon);
if (volume.getType() == VolumeInfo.TYPE_PUBLIC
&& volume.isMountedReadable()) {
@@ -73,12 +99,21 @@ public class StorageVolumePreference extends Preference {
@Override
protected void onBindView(View view) {
final TextView unmount = (TextView) view.findViewById(R.id.unmount);
final ImageView unmount = (ImageView) view.findViewById(R.id.unmount);
if (unmount != null) {
unmount.setText("\u23CF");
unmount.getDrawable().setTint(Color.parseColor("#8a000000"));
unmount.setOnClickListener(mUnmountListener);
}
final ProgressBar progress = (ProgressBar) view.findViewById(android.R.id.progress);
if (mVolume.getType() == VolumeInfo.TYPE_PRIVATE && mUsedPercent != -1) {
progress.setVisibility(View.VISIBLE);
progress.setProgress(mUsedPercent);
progress.setProgressTintList(ColorStateList.valueOf(mColor));
} else {
progress.setVisibility(View.GONE);
}
super.onBindView(view);
}

View File

@@ -1,78 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.deviceinfo;
import android.content.Context;
import android.preference.Preference;
import android.util.AttributeSet;
import android.view.View;
import com.android.settings.R;
import com.google.android.collect.Lists;
import java.util.Collections;
import java.util.List;
/**
* Creates a percentage bar chart inside a preference.
*/
public class UsageBarPreference extends Preference {
private PercentageBarChart mChart = null;
private final List<PercentageBarChart.Entry> mEntries = Lists.newArrayList();
public UsageBarPreference(Context context) {
this(context, null);
}
public UsageBarPreference(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public UsageBarPreference(Context context, AttributeSet attrs, int defStyle) {
this(context, attrs, defStyle, 0);
}
public UsageBarPreference(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setLayoutResource(R.layout.preference_memoryusage);
}
public void addEntry(int order, float percentage, int color) {
mEntries.add(PercentageBarChart.createEntry(order, percentage, color));
Collections.sort(mEntries);
}
@Override
protected void onBindView(View view) {
super.onBindView(view);
mChart = (PercentageBarChart) view.findViewById(R.id.percentage_bar_chart);
mChart.setEntries(mEntries);
}
public void commit() {
if (mChart != null) {
mChart.invalidate();
}
}
public void clear() {
mEntries.clear();
}
}

View File

@@ -16,7 +16,6 @@
package com.android.settings.widget;
import static android.net.TrafficStats.GB_IN_BYTES;
import static android.net.TrafficStats.MB_IN_BYTES;
import android.content.Context;
@@ -29,8 +28,11 @@ import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.format.Formatter;
import android.text.format.Formatter.BytesResult;
import android.text.format.Time;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
@@ -533,33 +535,11 @@ public class ChartDataUsageView extends ChartView {
@Override
public long buildLabel(Resources res, SpannableStringBuilder builder, long value) {
final CharSequence unit;
final long unitFactor;
if (value < 1000 * MB_IN_BYTES) {
unit = res.getText(com.android.internal.R.string.megabyteShort);
unitFactor = MB_IN_BYTES;
} else {
unit = res.getText(com.android.internal.R.string.gigabyteShort);
unitFactor = GB_IN_BYTES;
}
final double result = (double) value / unitFactor;
final double resultRounded;
final CharSequence size;
if (result < 10) {
size = String.format("%.1f", result);
resultRounded = (unitFactor * Math.round(result * 10)) / 10;
} else {
size = String.format("%.0f", result);
resultRounded = unitFactor * Math.round(result);
}
setText(builder, sSpanSize, size, "^1");
setText(builder, sSpanUnit, unit, "^2");
return (long) resultRounded;
final BytesResult result = Formatter.formatBytes(res, value,
Formatter.FLAG_SHORTER | Formatter.FLAG_CALCULATE_ROUNDED);
setText(builder, sSpanSize, result.value, "^1");
setText(builder, sSpanUnit, result.units, "^2");
return result.roundedBytes;
}
@Override