Making Settings > Storage multiprofile aware

Also fixing the order of preferences there.

Bug: 22223456
Bug: 22117317
Change-Id: I9261fe46bfce518fd1ce3d0faef07cffe6869e34
This commit is contained in:
Zoltan Szatmary-Ban
2015-07-01 16:45:34 +01:00
parent 2bd619d5ed
commit 6a00f6cf0b
2 changed files with 205 additions and 157 deletions

View File

@@ -39,6 +39,8 @@ 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.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.provider.DocumentsContract; import android.provider.DocumentsContract;
import android.text.TextUtils; import android.text.TextUtils;
@@ -66,7 +68,6 @@ import com.google.android.collect.Lists;
import java.io.File; import java.io.File;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -85,6 +86,18 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents"; private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents";
private static final int[] ITEMS_NO_SHOW_SHARED = new int[] {
R.string.storage_detail_apps,
};
private static final int[] ITEMS_SHOW_SHARED = new int[] {
R.string.storage_detail_apps,
R.string.storage_detail_images,
R.string.storage_detail_videos,
R.string.storage_detail_audio,
R.string.storage_detail_other
};
private StorageManager mStorageManager; private StorageManager mStorageManager;
private UserManager mUserManager; private UserManager mUserManager;
@@ -97,13 +110,10 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
private UserInfo mCurrentUser; private UserInfo mCurrentUser;
private StorageSummaryPreference mSummary; private StorageSummaryPreference mSummary;
private StorageItemPreference mApps; private List<StorageItemPreference> mItemPreferencePool = Lists.newArrayList();
private StorageItemPreference mImages; private List<PreferenceCategory> mHeaderPreferencePool = Lists.newArrayList();
private StorageItemPreference mVideos; private int mHeaderPoolIndex;
private StorageItemPreference mAudio; private int mItemPoolIndex;
private StorageItemPreference mOther;
private StorageItemPreference mCache;
private List<StorageItemPreference> mUsers = Lists.newArrayList();
private Preference mExplore; private Preference mExplore;
@@ -144,22 +154,7 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
getPreferenceScreen().setOrderingAsAdded(true); getPreferenceScreen().setOrderingAsAdded(true);
mSummary = new StorageSummaryPreference(context); mSummary = new StorageSummaryPreference(context);
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()); 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 StorageItemPreference userPref = new StorageItemPreference(
context, user.name, user.id);
mUsers.add(userPref);
}
mExplore = buildAction(R.string.storage_menu_explore); mExplore = buildAction(R.string.storage_menu_explore);
@@ -182,39 +177,46 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
screen.removeAll(); screen.removeAll();
addPreference(mSummary); addPreference(screen, mSummary);
final boolean showUsers = !mUsers.isEmpty(); List<UserInfo> allUsers = mUserManager.getUsers();
final int userCount = allUsers.size();
final boolean showHeaders = userCount > 1;
final boolean showShared = (mSharedVolume != null) && mSharedVolume.isMountedReadable(); final boolean showShared = (mSharedVolume != null) && mSharedVolume.isMountedReadable();
if (showUsers) { mItemPoolIndex = 0;
addPreference(new PreferenceHeader(context, mCurrentUser.name)); mHeaderPoolIndex = 0;
}
addPreference(mApps); int addedUserCount = 0;
if (showShared) { // Add current user and its profiles first
addPreference(mImages); for (int userIndex = 0; userIndex < userCount; ++userIndex) {
addPreference(mVideos); final UserInfo userInfo = allUsers.get(userIndex);
addPreference(mAudio); if (isProfileOf(mCurrentUser, userInfo)) {
addPreference(mOther); PreferenceCategory details = addCategory(screen,
} showHeaders ? userInfo.name : null);
addPreference(mCache); addDetailItems(details, showShared, userInfo.id);
if (showShared) { ++addedUserCount;
addPreference(mExplore);
}
if (showUsers) {
addPreference(new PreferenceHeader(context, R.string.storage_other_users));
for (Preference pref : mUsers) {
addPreference(pref);
} }
} }
for (int i = 0; i < screen.getPreferenceCount(); i++) { // Add rest of users
final Preference pref = screen.getPreference(i); if (userCount - addedUserCount > 0) {
if (pref instanceof StorageItemPreference) { PreferenceCategory otherUsers = addCategory(screen,
((StorageItemPreference) pref).setLoading(); getText(R.string.storage_other_users));
for (int userIndex = 0; userIndex < userCount; ++userIndex) {
final UserInfo userInfo = allUsers.get(userIndex);
if (!isProfileOf(mCurrentUser, userInfo)) {
addItem(otherUsers, /* titleRes */ 0, userInfo.name, userInfo.id);
}
} }
} }
addItem(screen, R.string.storage_detail_cached, null, UserHandle.USER_NULL);
if (showShared) {
addPreference(screen, mExplore);
}
final File file = mVolume.getPath(); final File file = mVolume.getPath();
final long totalBytes = file.getTotalSpace(); final long totalBytes = file.getTotalSpace();
final long freeBytes = file.getFreeSpace(); final long freeBytes = file.getFreeSpace();
@@ -230,13 +232,56 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
mMeasure.forceMeasure(); mMeasure.forceMeasure();
} }
private void addPreference(Preference pref) { private void addPreference(PreferenceGroup group, Preference pref) {
pref.setOrder(Preference.DEFAULT_ORDER); pref.setOrder(Preference.DEFAULT_ORDER);
getPreferenceScreen().addPreference(pref); group.addPreference(pref);
} }
private StorageItemPreference buildItem(int titleRes) { private PreferenceCategory addCategory(PreferenceGroup group, CharSequence title) {
return new StorageItemPreference(getActivity(), titleRes); PreferenceCategory category;
if (mHeaderPoolIndex < mHeaderPreferencePool.size()) {
category = mHeaderPreferencePool.get(mHeaderPoolIndex);
} else {
category = new PreferenceCategory(getActivity(), null,
com.android.internal.R.attr.preferenceCategoryStyle);
mHeaderPreferencePool.add(category);
}
category.setTitle(title);
category.removeAll();
addPreference(group, category);
++mHeaderPoolIndex;
return category;
}
private void addDetailItems(PreferenceCategory category, boolean showShared, int userId) {
final int[] itemsToAdd = (showShared ? ITEMS_SHOW_SHARED : ITEMS_NO_SHOW_SHARED);
for (int i = 0; i < itemsToAdd.length; ++i) {
addItem(category, itemsToAdd[i], null, userId);
}
}
private void addItem(PreferenceGroup group, int titleRes, CharSequence title, int userId) {
StorageItemPreference item;
if (mItemPoolIndex < mItemPreferencePool.size()) {
item = mItemPreferencePool.get(mItemPoolIndex);
} else {
item = buildItem();
mItemPreferencePool.add(item);
}
if (title != null) {
item.setTitle(title);
} else {
item.setTitle(titleRes);
}
item.setSummary(R.string.memory_calculating_size);
item.userHandle = userId;
addPreference(group, item);
++mItemPoolIndex;
}
private StorageItemPreference buildItem() {
final StorageItemPreference item = new StorageItemPreference(getActivity());
return item;
} }
private Preference buildAction(int titleRes) { private Preference buildAction(int titleRes) {
@@ -345,52 +390,67 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference pref) { public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference pref) {
// TODO: launch better intents for specific volume // TODO: launch better intents for specific volume
final int userId = (pref instanceof StorageItemPreference ?
((StorageItemPreference)pref).userHandle : -1);
final int itemTitleId = pref.getTitleRes();
Intent intent = null; Intent intent = null;
if (pref == mApps) { switch (itemTitleId) {
Bundle args = new Bundle(); case R.string.storage_detail_apps: {
args.putString(ManageApplications.EXTRA_CLASSNAME, StorageUseActivity.class.getName()); Bundle args = new Bundle();
args.putString(ManageApplications.EXTRA_VOLUME_UUID, mVolume.getFsUuid()); args.putString(ManageApplications.EXTRA_CLASSNAME,
args.putString(ManageApplications.EXTRA_VOLUME_NAME, mVolume.getDescription()); StorageUseActivity.class.getName());
intent = Utils.onBuildStartFragmentIntent(getActivity(), args.putString(ManageApplications.EXTRA_VOLUME_UUID, mVolume.getFsUuid());
ManageApplications.class.getName(), args, null, R.string.apps_storage, null, args.putString(ManageApplications.EXTRA_VOLUME_NAME, mVolume.getDescription());
false); intent = Utils.onBuildStartFragmentIntent(getActivity(),
ManageApplications.class.getName(), args, null, R.string.apps_storage, null,
false);
} else if (pref == mImages) { } break;
intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT); case R.string.storage_detail_images: {
intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "images_root")); intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "images_root"));
intent.addCategory(Intent.CATEGORY_DEFAULT);
} else if (pref == mVideos) { } break;
intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT); case R.string.storage_detail_videos: {
intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "videos_root")); intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "videos_root"));
intent.addCategory(Intent.CATEGORY_DEFAULT);
} else if (pref == mAudio) { } break;
intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT); case R.string.storage_detail_audio: {
intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root")); intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root"));
intent.addCategory(Intent.CATEGORY_DEFAULT);
} else if (pref == mOther) { } break;
OtherInfoFragment.show(this, mStorageManager.getBestVolumeDescription(mVolume), case R.string.storage_detail_other: {
mSharedVolume); OtherInfoFragment.show(this, mStorageManager.getBestVolumeDescription(mVolume),
return true; mSharedVolume);
return true;
} else if (pref == mCache) { }
ConfirmClearCacheFragment.show(this); case R.string.storage_detail_cached: {
return true; ConfirmClearCacheFragment.show(this);
return true;
} else if (pref == mExplore) { }
intent = mSharedVolume.buildBrowseIntent(); case R.string.storage_menu_explore: {
} intent = mSharedVolume.buildBrowseIntent();
} break;
if (mUsers.contains(pref)) { case 0: {
UserInfoFragment.show(this, pref.getTitle(), pref.getSummary()); UserInfoFragment.show(this, pref.getTitle(), pref.getSummary());
return true; return true;
}
} }
if (intent != null) { if (intent != null) {
try { try {
startActivity(intent); if (userId == -1) {
startActivity(intent);
} else {
getActivity().startActivityAsUser(intent, new UserHandle(userId));
}
} catch (ActivityNotFoundException e) { } catch (ActivityNotFoundException e) {
Log.w(TAG, "No activity found for " + intent); Log.w(TAG, "No activity found for " + intent);
} }
@@ -407,26 +467,49 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
}; };
private void updateDetails(MeasurementDetails details) { private void updateDetails(MeasurementDetails details) {
updatePreference(mApps, details.appsSize); PreferenceScreen screen = getPreferenceScreen();
final int preferenceCount = screen.getPreferenceCount();
final long imagesSize = totalValues(details.mediaSize, Environment.DIRECTORY_DCIM, for (int i = 0; i < preferenceCount; ++i) {
Environment.DIRECTORY_MOVIES, Environment.DIRECTORY_PICTURES); final Preference pref = screen.getPreference(i);
updatePreference(mImages, imagesSize); if (!(pref instanceof StorageItemPreference)) {
continue;
final long videosSize = totalValues(details.mediaSize, Environment.DIRECTORY_MOVIES); }
updatePreference(mVideos, videosSize); StorageItemPreference item = (StorageItemPreference)pref;
final int userId = item.userHandle;
final long audioSize = totalValues(details.mediaSize, Environment.DIRECTORY_MUSIC, final int itemTitleId = item.getTitleRes();
Environment.DIRECTORY_ALARMS, Environment.DIRECTORY_NOTIFICATIONS, switch (itemTitleId) {
Environment.DIRECTORY_RINGTONES, Environment.DIRECTORY_PODCASTS); case R.string.storage_detail_apps: {
updatePreference(mAudio, audioSize); updatePreference(item, details.appsSize.get(userId));
} break;
updatePreference(mCache, details.cacheSize); case R.string.storage_detail_images: {
updatePreference(mOther, details.miscSize); final long imagesSize = totalValues(details, userId,
Environment.DIRECTORY_DCIM, Environment.DIRECTORY_MOVIES,
for (StorageItemPreference userPref : mUsers) { Environment.DIRECTORY_PICTURES);
final long userSize = details.usersSize.get(userPref.userHandle); updatePreference(item, imagesSize);
updatePreference(userPref, userSize); } break;
case R.string.storage_detail_videos: {
final long videosSize = totalValues(details, userId,
Environment.DIRECTORY_MOVIES);
updatePreference(item, videosSize);
} break;
case R.string.storage_detail_audio: {
final long audioSize = totalValues(details, userId,
Environment.DIRECTORY_MUSIC,
Environment.DIRECTORY_ALARMS, Environment.DIRECTORY_NOTIFICATIONS,
Environment.DIRECTORY_RINGTONES, Environment.DIRECTORY_PODCASTS);
updatePreference(item, audioSize);
} break;
case R.string.storage_detail_other: {
updatePreference(item, details.miscSize.get(userId));
} break;
case R.string.storage_detail_cached: {
updatePreference(item, details.cacheSize);
} break;
case 0: {
final long userSize = details.usersSize.get(userId);
updatePreference(item, userSize);
} break;
}
} }
} }
@@ -434,26 +517,24 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
pref.setSummary(Formatter.formatFileSize(getActivity(), size)); pref.setSummary(Formatter.formatFileSize(getActivity(), size));
} }
/** private boolean isProfileOf(UserInfo user, UserInfo profile) {
* Return list of other users, excluding the current user. return user.id == profile.id ||
*/ (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
private List<UserInfo> getUsersExcluding(UserInfo excluding) { && user.profileGroupId == profile.profileGroupId);
final List<UserInfo> users = mUserManager.getUsers();
final Iterator<UserInfo> i = users.iterator();
while (i.hasNext()) {
if (i.next().id == excluding.id) {
i.remove();
}
}
return users;
} }
private static long totalValues(HashMap<String, Long> map, String... keys) { private static long totalValues(MeasurementDetails details, int userId, String... keys) {
long total = 0; long total = 0;
for (String key : keys) { HashMap<String, Long> map = details.mediaSize.get(userId);
if (map.containsKey(key)) { if (map != null) {
total += map.get(key); for (String key : keys) {
if (map.containsKey(key)) {
total += map.get(key);
}
} }
} else {
throw new IllegalStateException(
"MeasurementDetails mediaSize array does not have key for user " + userId);
} }
return total; return total;
} }
@@ -649,21 +730,4 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment {
} }
} }
} }
public static class PreferenceHeader extends Preference {
public PreferenceHeader(Context context, int titleRes) {
super(context, null, com.android.internal.R.attr.preferenceCategoryStyle);
setTitle(titleRes);
}
public PreferenceHeader(Context context, CharSequence title) {
super(context, null, com.android.internal.R.attr.preferenceCategoryStyle);
setTitle(title);
}
@Override
public boolean isEnabled() {
return false;
}
}
} }

View File

@@ -17,28 +17,12 @@
package com.android.settings.deviceinfo; package com.android.settings.deviceinfo;
import android.content.Context; import android.content.Context;
import android.os.UserHandle;
import android.preference.Preference; import android.preference.Preference;
import com.android.settings.R;
public class StorageItemPreference extends Preference { public class StorageItemPreference extends Preference {
public final int userHandle; public int userHandle;
public StorageItemPreference(Context context, int titleRes) { public StorageItemPreference(Context context) {
this(context, context.getText(titleRes), UserHandle.USER_NULL);
}
public StorageItemPreference(Context context, CharSequence title, int userHandle) {
super(context); super(context);
setTitle(title);
setSummary(R.string.memory_calculating_size);
this.userHandle = userHandle;
}
public void setLoading() {
setSummary(R.string.memory_calculating_size);
} }
} }