Merge "Better public volumes handling on secondary users." into pi-dev

This commit is contained in:
Jeff Sharkey
2018-03-29 17:13:42 +00:00
committed by Android (Google) Code Review
2 changed files with 87 additions and 61 deletions

View File

@@ -36,6 +36,7 @@ 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.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference; import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory; import android.support.v7.preference.PreferenceCategory;
import android.text.TextUtils; import android.text.TextUtils;
@@ -71,10 +72,11 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
private static final String TAG_VOLUME_UNMOUNTED = "volume_unmounted"; private static final String TAG_VOLUME_UNMOUNTED = "volume_unmounted";
private static final String TAG_DISK_INIT = "disk_init"; private static final String TAG_DISK_INIT = "disk_init";
private static final int METRICS_CATEGORY = MetricsEvent.DEVICEINFO_STORAGE;
static final int COLOR_PUBLIC = Color.parseColor("#ff9e9e9e"); static final int COLOR_PUBLIC = Color.parseColor("#ff9e9e9e");
static final int[] COLOR_PRIVATE = new int[] { static final int[] COLOR_PRIVATE = new int[]{
Color.parseColor("#ff26a69a"), Color.parseColor("#ff26a69a"),
Color.parseColor("#ffab47bc"), Color.parseColor("#ffab47bc"),
Color.parseColor("#fff2a600"), Color.parseColor("#fff2a600"),
@@ -94,7 +96,7 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
return MetricsEvent.DEVICEINFO_STORAGE; return METRICS_CATEGORY;
} }
@Override @Override
@@ -139,7 +141,7 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
}; };
private static boolean isInteresting(VolumeInfo vol) { private static boolean isInteresting(VolumeInfo vol) {
switch(vol.getType()) { switch (vol.getType()) {
case VolumeInfo.TYPE_PRIVATE: case VolumeInfo.TYPE_PRIVATE:
case VolumeInfo.TYPE_PUBLIC: case VolumeInfo.TYPE_PUBLIC:
return true; return true;
@@ -301,20 +303,7 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
return true; return true;
} else if (vol.getType() == VolumeInfo.TYPE_PUBLIC) { } else if (vol.getType() == VolumeInfo.TYPE_PUBLIC) {
if (vol.isMountedReadable()) { return handlePublicVolumeClick(getContext(), vol);
startActivity(vol.buildBrowseIntent());
return true;
} else {
final Bundle args = new Bundle();
args.putString(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
new SubSettingLauncher(getContext())
.setDestination(PublicVolumeSettings.class.getCanonicalName())
.setTitle(-1)
.setSourceMetricsCategory(getMetricsCategory())
.setArguments(args)
.launch();
return true;
}
} }
} else if (key.startsWith("disk:")) { } else if (key.startsWith("disk:")) {
@@ -328,7 +317,7 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
args.putString(VolumeRecord.EXTRA_FS_UUID, key); args.putString(VolumeRecord.EXTRA_FS_UUID, key);
new SubSettingLauncher(getContext()) new SubSettingLauncher(getContext())
.setDestination(PrivateVolumeForget.class.getCanonicalName()) .setDestination(PrivateVolumeForget.class.getCanonicalName())
.setTitle(R.string.storage_menu_forget) .setTitle(R.string.storage_menu_forget)
.setSourceMetricsCategory(getMetricsCategory()) .setSourceMetricsCategory(getMetricsCategory())
.setArguments(args) .setArguments(args)
.launch(); .launch();
@@ -338,6 +327,25 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
return false; return false;
} }
@VisibleForTesting
static boolean handlePublicVolumeClick(Context context, VolumeInfo vol) {
final Intent intent = vol.buildBrowseIntent();
if (vol.isMountedReadable() && intent != null) {
context.startActivity(intent);
return true;
} else {
final Bundle args = new Bundle();
args.putString(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
new SubSettingLauncher(context)
.setDestination(PublicVolumeSettings.class.getCanonicalName())
.setTitle(-1)
.setSourceMetricsCategory(METRICS_CATEGORY)
.setArguments(args)
.launch();
return true;
}
}
public static class MountTask extends AsyncTask<Void, Void, Exception> { public static class MountTask extends AsyncTask<Void, Void, Exception> {
private final Context mContext; private final Context mContext;
private final StorageManager mStorageManager; private final StorageManager mStorageManager;
@@ -440,40 +448,45 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
builder.setPositiveButton(R.string.storage_menu_mount, builder.setPositiveButton(R.string.storage_menu_mount,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
/** /**
* Check if an {@link RestrictedLockUtils#sendShowAdminSupportDetailsIntent admin * Check if an {@link
* details intent} should be shown for the restriction and show it. * RestrictedLockUtils#sendShowAdminSupportDetailsIntent admin
* * details intent} should be shown for the restriction and show it.
* @param restriction The restriction to check *
* @return {@code true} iff a intent was shown. * @param restriction The restriction to check
*/ * @return {@code true} iff a intent was shown.
private boolean wasAdminSupportIntentShown(@NonNull String restriction) { */
EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced( private boolean wasAdminSupportIntentShown(@NonNull String restriction) {
getActivity(), restriction, UserHandle.myUserId()); EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
boolean hasBaseUserRestriction = RestrictedLockUtils.hasBaseUserRestriction( getActivity(), restriction, UserHandle.myUserId());
getActivity(), restriction, UserHandle.myUserId()); boolean hasBaseUserRestriction =
if (admin != null && !hasBaseUserRestriction) { RestrictedLockUtils.hasBaseUserRestriction(
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getActivity(), admin); getActivity(), restriction, UserHandle.myUserId());
return true; if (admin != null && !hasBaseUserRestriction) {
} RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getActivity(),
admin);
return true;
}
return false; return false;
} }
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if (wasAdminSupportIntentShown(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA)) { if (wasAdminSupportIntentShown(
return; UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA)) {
} return;
}
if (vol.disk != null && vol.disk.isUsb() && if (vol.disk != null && vol.disk.isUsb() &&
wasAdminSupportIntentShown(UserManager.DISALLOW_USB_FILE_TRANSFER)) { wasAdminSupportIntentShown(
return; UserManager.DISALLOW_USB_FILE_TRANSFER)) {
} return;
}
new MountTask(context, vol).execute(); new MountTask(context, vol).execute();
} }
}); });
builder.setNegativeButton(R.string.cancel, null); builder.setNegativeButton(R.string.cancel, null);
return builder.create(); return builder.create();
@@ -511,13 +524,13 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
builder.setPositiveButton(R.string.storage_menu_set_up, builder.setPositiveButton(R.string.storage_menu_set_up,
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
final Intent intent = new Intent(context, StorageWizardInit.class); final Intent intent = new Intent(context, StorageWizardInit.class);
intent.putExtra(DiskInfo.EXTRA_DISK_ID, diskId); intent.putExtra(DiskInfo.EXTRA_DISK_ID, diskId);
startActivity(intent); startActivity(intent);
} }
}); });
builder.setNegativeButton(R.string.cancel, null); builder.setNegativeButton(R.string.cancel, null);
return builder.create(); return builder.create();
@@ -586,7 +599,7 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
for (VolumeInfo vol : vols) { for (VolumeInfo vol : vols) {
if (isInteresting(vol)) { if (isInteresting(vol)) {
data.title = storage.getBestVolumeDescription(vol); data.title = storage.getBestVolumeDescription(vol);
data.key = "storage_settings_volume_" +vol.id; data.key = "storage_settings_volume_" + vol.id;
data.screenTitle = context.getString(R.string.storage_settings); data.screenTitle = context.getString(R.string.storage_settings);
result.add(data); result.add(data);
} }

View File

@@ -16,14 +16,17 @@
package com.android.settings.deviceinfo; package com.android.settings.deviceinfo;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.Activity; import android.app.Activity;
import android.app.usage.StorageStatsManager; import android.app.usage.StorageStatsManager;
import android.content.Intent;
import android.icu.text.NumberFormat; import android.icu.text.NumberFormat;
import android.os.storage.VolumeInfo; import android.os.storage.VolumeInfo;
import android.text.format.Formatter; import android.text.format.Formatter;
@@ -71,14 +74,14 @@ public class StorageSettingsTest {
when(volumeInfo.isMountedReadable()).thenReturn(true); when(volumeInfo.isMountedReadable()).thenReturn(true);
when(volumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE); when(volumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
when(mStorageManagerVolumeProvider when(mStorageManagerVolumeProvider
.getTotalBytes(nullable(StorageStatsManager.class), nullable(VolumeInfo.class))) .getTotalBytes(nullable(StorageStatsManager.class), nullable(VolumeInfo.class)))
.thenReturn(500L); .thenReturn(500L);
when(mStorageManagerVolumeProvider when(mStorageManagerVolumeProvider
.getFreeBytes(nullable(StorageStatsManager.class), nullable(VolumeInfo.class))) .getFreeBytes(nullable(StorageStatsManager.class), nullable(VolumeInfo.class)))
.thenReturn(0L); .thenReturn(0L);
ReflectionHelpers ReflectionHelpers
.setField(provider, "mStorageManagerVolumeProvider", mStorageManagerVolumeProvider); .setField(provider, "mStorageManagerVolumeProvider", mStorageManagerVolumeProvider);
ReflectionHelpers.setField(provider, "mContext", RuntimeEnvironment.application); ReflectionHelpers.setField(provider, "mContext", RuntimeEnvironment.application);
provider.setListening(true); provider.setListening(true);
@@ -89,4 +92,14 @@ public class StorageSettingsTest {
RuntimeEnvironment.application.getString( RuntimeEnvironment.application.getString(
R.string.storage_summary, percentage, freeSpace)); R.string.storage_summary, percentage, freeSpace));
} }
@Test
public void handlePublicVolumeClick_startsANonNullActivityWhenVolumeHasNoBrowse() {
VolumeInfo volumeInfo = mock(VolumeInfo.class, RETURNS_DEEP_STUBS);
when(volumeInfo.isMountedReadable()).thenReturn(true);
StorageSettings.handlePublicVolumeClick(mActivity, volumeInfo);
verify(mActivity, never()).startActivity(null);
verify(mActivity).startActivity(any(Intent.class));
}
} }