diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4bbd75b..af9c3b4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1415,15 +1415,31 @@
                 <category android:name="android.intent.category.VOICE_LAUNCH" />
             </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                android:value="com.android.settings.deviceinfo.Memory" />
+                android:value="com.android.settings.deviceinfo.StorageSettings" />
             <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
                 android:resource="@id/storage_settings" />
             <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                 android:value="true" />
         </activity>
 
-        <activity android:name=".deviceinfo.MiscFilesHandler"
-                android:theme="@style/Theme.SubSettingsDialogWhenLarge"/>
+        <activity
+                android:name="Settings$StorageVolumeSettingsActivity"
+                android:label="@string/storage_settings_title"
+                android:taskAffinity="com.android.settings"
+                android:parentActivityName="Settings$StorageSettingsActivity">
+            <intent-filter>
+                <action android:name="android.provider.action.DOCUMENT_ROOT_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data
+                    android:scheme="content"
+                    android:host="com.android.externalstorage.documents"
+                    android:mimeType="vnd.android.document/root" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.deviceinfo.PublicVolumeSettings" />
+            <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
+                android:resource="@id/storage_settings" />
+        </activity>
 
         <activity android:name="ApnEditor"
                 android:label="@string/apn_edit">
diff --git a/res/layout/preference_storage_action.xml b/res/layout/preference_storage_action.xml
new file mode 100644
index 0000000..10f138b
--- /dev/null
+++ b/res/layout/preference_storage_action.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="match_parent"
+    android:orientation="horizontal">
+
+    <TextView
+        android:id="@+id/unmount"
+        android:layout_width="wrap_content"
+        android:layout_height="fill_parent"
+        android:paddingStart="16dip"
+        android:paddingEnd="16dip"
+        android:contentDescription="@string/storage_menu_unmount"
+        android:layout_gravity="center"
+        android:gravity="center"
+        android:textSize="30sp"
+        android:background="?android:attr/selectableItemBackground" />
+
+    <!--
+    <ImageView
+        android:id="@+id/eject"
+        android:layout_width="wrap_content"
+        android:layout_height="fill_parent"
+        android:paddingStart="16dip"
+        android:paddingEnd="16dip"
+        android:src="@drawable/ic_sync_green_holo"
+        android:contentDescription="@string/storage_menu_eject"
+        android:layout_gravity="center"
+        android:background="?android:attr/selectableItemBackground" />
+    -->
+</LinearLayout>
diff --git a/res/menu/storage_volume.xml b/res/menu/storage_volume.xml
new file mode 100644
index 0000000..093a4bb
--- /dev/null
+++ b/res/menu/storage_volume.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:id="@+id/storage_rename"
+        android:title="@string/storage_menu_rename" />
+    <item
+        android:id="@+id/storage_mount"
+        android:title="@string/storage_menu_mount" />
+    <item
+        android:id="@+id/storage_unmount"
+        android:title="@string/storage_menu_unmount" />
+    <item
+        android:id="@+id/storage_format"
+        android:title="@string/storage_menu_format" />
+    <item
+        android:id="@+id/storage_usb"
+        android:title="@string/storage_menu_usb" />
+</menu>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 4f1eb97..16f1970 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -316,6 +316,12 @@
         <item>TTLS</item>
         <!-- Do not translate. -->
         <item>PWD</item>
+        <!-- Do not translate. -->
+        <item>SIM</item>
+        <!-- Do not translate. -->
+        <item>AKA</item>
+        <!-- Do not translate. -->
+        <item>AKA\'</item>
     </string-array>
 
    <!-- Wi-Fi WPS setup for p2p connections.  -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 50ba70c..a608410 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -593,6 +593,9 @@
     <!-- Button label for generic forget action [CHAR LIMIT=20] -->
     <string name="forget">Forget</string>
 
+    <!-- Button label for generic save action [CHAR LIMIT=20] -->
+    <string name="save">Save</string>
+
     <!-- Title of the Settings activity shown within the application itself. -->
     <string name="settings_label">Settings</string>
     <!-- Title of the Settings activity shown in the Launcher. [CHAR LIMIT=20] -->
@@ -1815,12 +1818,10 @@
     <string-array name="wifi_calling_mode_choices">
         <item>Wi-Fi preferred</item>
         <item>Cellular preferred</item>
-        <item>Wi-Fi only</item>
     </string-array>
     <string-array name="wifi_calling_mode_values">
         <item>"2"</item>
         <item>"1"</item>
-        <item>"0"</item>
     </string-array>
     <!-- Wi-Fi Calling settings. Text displayed when Wi-Fi Calling is off -->
     <string name="wifi_calling_off_explanation">When Wi-Fi calling is on, your phone can route calls via Wi-Fi networks or your carrier\'s network, depending on your preference and which signal is stronger. Before turning on this feature, check with your carrier regarding fees and other details.</string>
@@ -2187,7 +2188,7 @@
     <!-- SD card & phone storage settings summary. Displayed when the total memory usage is being calculated. Will be replaced with a number like "12.3 GB" when finished calucating. [CHAR LIMIT=30] -->
     <string name="memory_calculating_size">Calculating\u2026</string>
     <!-- SD card & phone storage settings title. Displayed as a title when showing the total usage of applications installed. Below it will be a number like "123.4 MB" indicating used storage. [CHAR LIMIT=50] -->
-    <string name="memory_apps_usage">Apps (app data &amp; media content)</string>
+    <string name="memory_apps_usage">Apps &amp; app data</string>
     <!-- SD card & phone storage settings title. Displayed as a title when showing the total usage of media on the device. Below it will be a number like "123.4 MB" indicating used storage. [CHAR LIMIT=50] -->
     <string name="memory_media_usage">Media</string>
     <!-- SD card & phone storage settings title. Displayed as a title when showing the total usage of /sdcard/Download on the device. Below it will be a number like "123.4 MB" indicating used storage. [CHAR LIMIT=50] -->
@@ -2197,7 +2198,7 @@
     <!-- SD card & phone storage settings title. Displayed as a title when showing the total usage of audio files in /sdcard on the device. Below it will be a number like "123.4 MB" indicating used storage. [CHAR LIMIT=50] -->
     <string name="memory_music_usage">Audio (music, ringtones, podcasts, etc.)</string>
     <!-- SD card & phone storage settings title. Displayed as a title when showing the total usage of misc files on the device. Below it will be a number like "123.4 MB" indicating used storage. [CHAR LIMIT=50] -->
-    <string name="memory_media_misc_usage">Misc.</string>
+    <string name="memory_media_misc_usage">Other files</string>
     <!-- Storage item representing all cached data on device. [CHAR LIMIT=48] -->
     <string name="memory_media_cache_usage">Cached data</string>
     <!-- SD card & phone storage settings item title that will result in the phone unmounting the SD card.  This will be done before the user phyiscally removes the SD card from the phone.  Kind of like the "Safely remove" on some operating systems.   [CHAR LIMIT=25] -->
@@ -2272,6 +2273,16 @@
     <!-- Settings item summary when storage is running low [CHAR LIMIT=NONE] -->
     <string name="storage_low_summary">Some system functions, such as syncing, may not work correctly. Try to free space by deleting or unpinning items, such as apps or media content.</string>
 
+    <!-- Storage setting.  Menu option for renaming a storage device [CHAR LIMIT=30]-->
+    <string name="storage_menu_rename">Rename</string>
+    <!-- Storage setting.  Menu option for mounting a storage device [CHAR LIMIT=30]-->
+    <string name="storage_menu_mount">Mount</string>
+    <!-- Storage setting.  Menu option for unmounting a storage device [CHAR LIMIT=30]-->
+    <string name="storage_menu_unmount">Eject</string>
+    <!-- Storage setting.  Menu option for erasing and formatting a storage device [CHAR LIMIT=30]-->
+    <string name="storage_menu_format">Erase &amp; format</string>
+    <!-- Storage setting.  Menu option for erasing and formatting a storage device [CHAR LIMIT=30]-->
+    <string name="storage_menu_format_internal">Erase &amp; format as internal storage</string>
     <!-- Storage setting.  Menu option for USB transfer settings [CHAR LIMIT=30]-->
     <string name="storage_menu_usb">USB computer connection</string>
 
@@ -2295,6 +2306,32 @@
     <!-- Section header above list of other users storage [CHAR LIMIT=32] -->
     <string name="storage_other_users">Other users</string>
 
+    <!-- Section header above list of internal storage devices [CHAR LIMIT=30]-->
+    <string name="storage_internal_title">Device storage</string>
+    <!-- Section header above list of external storage devices [CHAR LIMIT=30]-->
+    <string name="storage_external_title">Removable storage</string>
+
+    <!-- Summary of a single storage volume, constrasting available and total storage space. [CHAR LIMIT=48]-->
+    <string name="storage_volume_summary"><xliff:g id="free" example="1.2GB">%1$s</xliff:g> free (Total <xliff:g id="total" example="32GB">%2$s</xliff:g>)</string>
+
+    <!-- Toast informing that storage mount operation was successful. [CHAR LIMIT=64]-->
+    <string name="storage_mount_success"><xliff:g id="name" example="SD card">%1$s</xliff:g> is mounted</string>
+    <!-- Toast informing that storage unmount operation failed. [CHAR LIMIT=64]-->
+    <string name="storage_mount_failure">Couldn\'t mount <xliff:g id="name" example="SD card">%1$s</xliff:g></string>
+
+    <!-- Toast informing that storage unmount operation was successful. [CHAR LIMIT=64]-->
+    <string name="storage_unmount_success"><xliff:g id="name" example="SD card">%1$s</xliff:g> is safely ejected</string>
+    <!-- Toast informing that storage unmount operation failed. [CHAR LIMIT=64]-->
+    <string name="storage_unmount_failure">Couldn\'t safely eject <xliff:g id="name" example="SD card">%1$s</xliff:g></string>
+
+    <!-- Toast informing that storage format operation was successful. [CHAR LIMIT=64]-->
+    <string name="storage_format_success"><xliff:g id="name" example="SD card">%1$s</xliff:g> is formatted</string>
+    <!-- Toast informing that storage format operation failed. [CHAR LIMIT=64]-->
+    <string name="storage_format_failure">Couldn\'t format <xliff:g id="name" example="SD card">%1$s</xliff:g></string>
+
+    <!-- Title of dialog prompting user to rename a storage volume [CHAR LIMIT=32]-->
+    <string name="storage_rename_title">Rename storage</string>
+
     <!-- Phone info screen, section titles: -->
     <string name="battery_status_title">Battery status</string>
     <!-- Phone info screen, section titles: -->
diff --git a/res/xml/dashboard_categories.xml b/res/xml/dashboard_categories.xml
index 0d8c1ac..78fe0e7 100644
--- a/res/xml/dashboard_categories.xml
+++ b/res/xml/dashboard_categories.xml
@@ -106,7 +106,7 @@
         <dashboard-tile
                 android:id="@+id/storage_settings"
                 android:title="@string/storage_settings"
-                android:fragment="com.android.settings.deviceinfo.Memory"
+                android:fragment="com.android.settings.deviceinfo.StorageSettings"
                 android:icon="@drawable/ic_settings_storage"
                 />
 
diff --git a/res/xml/device_info_storage.xml b/res/xml/device_info_storage.xml
new file mode 100644
index 0000000..19c5982
--- /dev/null
+++ b/res/xml/device_info_storage.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
+    android:title="@string/storage_settings"
+    settings:keywords="@string/keywords_storage">
+
+    <PreferenceCategory
+        android:key="storage_internal"
+        android:title="@string/storage_internal_title" />
+
+    <PreferenceCategory
+        android:key="storage_external"
+        android:title="@string/storage_external_title" />
+
+</PreferenceScreen>
diff --git a/res/xml/device_info_memory.xml b/res/xml/device_info_storage_volume.xml
similarity index 64%
rename from res/xml/device_info_memory.xml
rename to res/xml/device_info_storage_volume.xml
index 38cc94a..35435d7 100644
--- a/res/xml/device_info_memory.xml
+++ b/res/xml/device_info_storage_volume.xml
@@ -4,9 +4,9 @@
      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.
@@ -14,11 +14,10 @@
      limitations under the License.
 -->
 
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-                  xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
-        android:title="@string/storage_settings"
-        settings:keywords="@string/keywords_storage">
-
-<!-- Preference categories are dynamically created based on the list of available storage volumes -->
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
+    android:title="@string/storage_settings"
+    settings:keywords="@string/keywords_storage">
 
 </PreferenceScreen>
diff --git a/src/com/android/settings/FingerprintEnroll.java b/src/com/android/settings/FingerprintEnroll.java
index 96e612b..a6424e5 100644
--- a/src/com/android/settings/FingerprintEnroll.java
+++ b/src/com/android/settings/FingerprintEnroll.java
@@ -254,7 +254,7 @@
                 case EnrollingStart:
                     mEnrollmentSteps = -1;
                     long challenge = 0x12345; // TODO: get from keyguard confirmation
-                    mFingerprintManager.enroll(challenge, mEnrollmentCallback, mEnrollmentCancel,0);
+                    mFingerprintManager.enroll(challenge, mEnrollmentCancel, mEnrollmentCallback, 0);
                     mProgressBar.setProgress(0);
                     mEnrolling = true;
                     startFingerprintAnimator(); // XXX hack - this should follow fingerprint detection
diff --git a/src/com/android/settings/FingerprintSettings.java b/src/com/android/settings/FingerprintSettings.java
index c134cfb..b4d6a4f 100644
--- a/src/com/android/settings/FingerprintSettings.java
+++ b/src/com/android/settings/FingerprintSettings.java
@@ -24,6 +24,7 @@
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.CancellationSignal;
 import android.os.Handler;
 import android.preference.Preference;
 import android.preference.Preference.OnPreferenceChangeListener;
@@ -92,8 +93,10 @@
         private FingerprintManager mFingerprintManager;
         private EditText mDialogTextField;
         private PreferenceGroup mManageCategory;
+        private CancellationSignal mFingerprintCancel;
+        private int mMaxFingerprintAttempts;
+
         private AuthenticationCallback mAuthCallback = new AuthenticationCallback() {
-            int mAttempts;
             @Override
             public void onAuthenticationSucceeded(AuthenticationResult result) {
                 mHandler.obtainMessage(MSG_HIGHLIGHT_FINGERPRINT_ITEM,
@@ -101,20 +104,16 @@
                 retryFingerprint(true);
             }
 
+            public void onAuthenticationFailed() {
+                retryFingerprint(true);
+            };
+
             @Override
             public void onAuthenticationError(int errMsgId, CharSequence errString) {
                 Toast.makeText(getActivity(), errString, Toast.LENGTH_SHORT);
-                retryFingerprint(false);
-            }
-
-            private void retryFingerprint(boolean resetAttempts) {
-                if (resetAttempts) {
-                    mAttempts = 0;
+                if (errMsgId != FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
+                    retryFingerprint(false);
                 }
-                if (mAttempts < MAX_RETRY_ATTEMPTS) {
-                    mFingerprintManager.authenticate(null, mAuthCallback, null, 0);
-                }
-                mAttempts++;
             }
 
             @Override
@@ -148,6 +147,24 @@
             };
         };
 
+        private void stopFingerprint() {
+            if (mFingerprintCancel != null) {
+                mFingerprintCancel.cancel();
+                mFingerprintCancel = null;
+            }
+        }
+
+        private void retryFingerprint(boolean resetAttempts) {
+            if (resetAttempts) {
+                mMaxFingerprintAttempts = 0;
+            }
+            if (mMaxFingerprintAttempts < MAX_RETRY_ATTEMPTS) {
+                mFingerprintCancel = new CancellationSignal();
+                mFingerprintManager.authenticate(null, mFingerprintCancel, mAuthCallback, 0);
+            }
+            mMaxFingerprintAttempts++;
+        }
+
         @Override
         protected int getMetricsCategory() {
             return MetricsLogger.FINGERPRINT;
@@ -158,7 +175,6 @@
             super.onCreate(savedInstanceState);
             mFingerprintManager = (FingerprintManager) getActivity().getSystemService(
                     Context.FINGERPRINT_SERVICE);
-            mFingerprintManager.authenticate(null, mAuthCallback, null, 0);
         }
 
         protected void removeFingerprintPreference(int fingerprintId) {
@@ -252,6 +268,13 @@
             // Make sure we reload the preference hierarchy since fingerprints may be added,
             // deleted or renamed.
             createPreferenceHierarchy();
+            retryFingerprint(true);
+        }
+
+        @Override
+        public void onPause() {
+            super.onPause();
+            stopFingerprint();
         }
 
         @Override
@@ -260,6 +283,7 @@
             if (KEY_FINGERPRINT_ADD.equals(key)) {
                 Intent intent = new Intent();
                 intent.setClassName("com.android.settings", FingerprintEnroll.class.getName());
+                stopFingerprint();
                 startActivityForResult(intent, ADD_FINGERPRINT_REQUEST);
             } else if (pref instanceof FingerprintPreference) {
                 FingerprintPreference fpref = (FingerprintPreference) pref;
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index b58159e..fe0df59 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -33,6 +33,7 @@
     public static class VpnSettingsActivity extends SettingsActivity { /* empty */ }
     public static class DateTimeSettingsActivity extends SettingsActivity { /* empty */ }
     public static class StorageSettingsActivity extends SettingsActivity { /* empty */ }
+    public static class StorageVolumeSettingsActivity extends SettingsActivity { /* empty */ }
     public static class WifiSettingsActivity extends SettingsActivity { /* empty */ }
     public static class WifiP2pSettingsActivity extends SettingsActivity { /* empty */ }
     public static class InputMethodAndLanguageSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 24209b0..7bfd249 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -82,7 +82,8 @@
 import com.android.settings.dashboard.DashboardTile;
 import com.android.settings.dashboard.NoHomeDialogFragment;
 import com.android.settings.dashboard.SearchResultsSummary;
-import com.android.settings.deviceinfo.Memory;
+import com.android.settings.deviceinfo.PublicVolumeSettings;
+import com.android.settings.deviceinfo.StorageSettings;
 import com.android.settings.deviceinfo.UsbSettings;
 import com.android.settings.fuelgauge.BatterySaverSettings;
 import com.android.settings.fuelgauge.PowerUsageSummary;
@@ -305,7 +306,8 @@
             CaptionPropertiesFragment.class.getName(),
             com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.class.getName(),
             TextToSpeechSettings.class.getName(),
-            Memory.class.getName(),
+            StorageSettings.class.getName(),
+            PublicVolumeSettings.class.getName(),
             DevelopmentSettings.class.getName(),
             UsbSettings.class.getName(),
             AndroidBeam.class.getName(),
diff --git a/src/com/android/settings/deviceinfo/Memory.java b/src/com/android/settings/deviceinfo/Memory.java
deleted file mode 100644
index a07f7c2..0000000
--- a/src/com/android/settings/deviceinfo/Memory.java
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Copyright (C) 2008 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.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.hardware.usb.UsbManager;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserManager;
-import android.os.storage.IMountService;
-import android.os.storage.StorageEventListener;
-import android.os.storage.StorageManager;
-import android.os.storage.StorageVolume;
-import android.preference.Preference;
-import android.preference.PreferenceScreen;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.widget.Toast;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableRaw;
-import com.google.android.collect.Lists;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Panel showing storage usage on disk for known {@link StorageVolume} returned
- * by {@link StorageManager}. Calculates and displays usage of data types.
- */
-public class Memory extends SettingsPreferenceFragment implements Indexable {
-    private static final String TAG = "MemorySettings";
-
-    private static final String TAG_CONFIRM_CLEAR_CACHE = "confirmClearCache";
-
-    private static final int DLG_CONFIRM_UNMOUNT = 1;
-    private static final int DLG_ERROR_UNMOUNT = 2;
-
-    // The mountToggle Preference that has last been clicked.
-    // Assumes no two successive unmount event on 2 different volumes are performed before the first
-    // one's preference is disabled
-    private static Preference sLastClickedMountToggle;
-    private static String sClickedMountPoint;
-
-    // Access using getMountService()
-    private IMountService mMountService;
-    private StorageManager mStorageManager;
-    private UsbManager mUsbManager;
-
-    private ArrayList<StorageVolumePreferenceCategory> mCategories = Lists.newArrayList();
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsLogger.DEVICEINFO_MEMORY;
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        final Context context = getActivity();
-
-        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
-
-        mStorageManager = StorageManager.from(context);
-        mStorageManager.registerListener(mStorageListener);
-
-        addPreferencesFromResource(R.xml.device_info_memory);
-
-        addCategory(StorageVolumePreferenceCategory.buildForInternal(context));
-
-        final StorageVolume[] storageVolumes = mStorageManager.getVolumeList();
-        for (StorageVolume volume : storageVolumes) {
-            if (!volume.isEmulated()) {
-                addCategory(StorageVolumePreferenceCategory.buildForPhysical(context, volume));
-            }
-        }
-
-        setHasOptionsMenu(true);
-    }
-
-    private void addCategory(StorageVolumePreferenceCategory category) {
-        mCategories.add(category);
-        getPreferenceScreen().addPreference(category);
-        category.init();
-    }
-
-    private boolean isMassStorageEnabled() {
-        // Mass storage is enabled if primary volume supports it
-        final StorageVolume[] volumes = mStorageManager.getVolumeList();
-        final StorageVolume primary = StorageManager.getPrimaryVolume(volumes);
-        return primary != null && primary.allowMassStorage();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED);
-        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
-        intentFilter.addDataScheme("file");
-        getActivity().registerReceiver(mMediaScannerReceiver, intentFilter);
-
-        intentFilter = new IntentFilter();
-        intentFilter.addAction(UsbManager.ACTION_USB_STATE);
-        getActivity().registerReceiver(mMediaScannerReceiver, intentFilter);
-
-        for (StorageVolumePreferenceCategory category : mCategories) {
-            category.onResume();
-        }
-    }
-
-    StorageEventListener mStorageListener = new StorageEventListener() {
-        @Override
-        public void onStorageStateChanged(String path, String oldState, String newState) {
-            Log.i(TAG, "Received storage state changed notification that " + path +
-                    " changed state from " + oldState + " to " + newState);
-            for (StorageVolumePreferenceCategory category : mCategories) {
-                final StorageVolume volume = category.getStorageVolume();
-                if (volume != null && path.equals(volume.getPath())) {
-                    category.onStorageStateChanged();
-                    break;
-                }
-            }
-        }
-    };
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        getActivity().unregisterReceiver(mMediaScannerReceiver);
-        for (StorageVolumePreferenceCategory category : mCategories) {
-            category.onPause();
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-        if (mStorageManager != null && mStorageListener != null) {
-            mStorageManager.unregisterListener(mStorageListener);
-        }
-        super.onDestroy();
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        inflater.inflate(R.menu.storage, menu);
-    }
-
-    @Override
-    public void onPrepareOptionsMenu(Menu menu) {
-        final MenuItem usb = menu.findItem(R.id.storage_usb);
-        UserManager um = (UserManager)getActivity().getSystemService(Context.USER_SERVICE);
-        boolean usbItemVisible = !isMassStorageEnabled()
-                && !um.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);
-        usb.setVisible(usbItemVisible);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.storage_usb:
-                if (getActivity() instanceof SettingsActivity) {
-                    ((SettingsActivity) getActivity()).startPreferencePanel(
-                            UsbSettings.class.getCanonicalName(),
-                            null, R.string.storage_title_usb, null, this, 0);
-                } else {
-                    startFragment(this, UsbSettings.class.getCanonicalName(),
-                            R.string.storage_title_usb, -1, null);
-                }
-                return true;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    private synchronized IMountService getMountService() {
-       if (mMountService == null) {
-           IBinder service = ServiceManager.getService("mount");
-           if (service != null) {
-               mMountService = IMountService.Stub.asInterface(service);
-           } else {
-               Log.e(TAG, "Can't get mount service");
-           }
-       }
-       return mMountService;
-    }
-
-    @Override
-    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-        if (StorageVolumePreferenceCategory.KEY_CACHE.equals(preference.getKey())) {
-            ConfirmClearCacheFragment.show(this);
-            return true;
-        }
-
-        for (StorageVolumePreferenceCategory category : mCategories) {
-            Intent intent = category.intentForClick(preference);
-            if (intent != null) {
-                // Don't go across app boundary if monkey is running
-                if (!Utils.isMonkeyRunning()) {
-                    try {
-                        startActivity(intent);
-                    } catch (ActivityNotFoundException anfe) {
-                        Log.w(TAG, "No activity found for intent " + intent);
-                    }
-                }
-                return true;
-            }
-
-            final StorageVolume volume = category.getStorageVolume();
-            if (volume != null && category.mountToggleClicked(preference)) {
-                sLastClickedMountToggle = preference;
-                sClickedMountPoint = volume.getPath();
-                String state = mStorageManager.getVolumeState(volume.getPath());
-                if (Environment.MEDIA_MOUNTED.equals(state) ||
-                        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
-                    unmount();
-                } else {
-                    mount();
-                }
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private final BroadcastReceiver mMediaScannerReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(UsbManager.ACTION_USB_STATE)) {
-               boolean isUsbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
-               String usbFunction = mUsbManager.getDefaultFunction();
-               for (StorageVolumePreferenceCategory category : mCategories) {
-                   category.onUsbStateChanged(isUsbConnected, usbFunction);
-               }
-            } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
-                for (StorageVolumePreferenceCategory category : mCategories) {
-                    category.onMediaScannerFinished();
-                }
-            }
-        }
-    };
-
-    @Override
-    public Dialog onCreateDialog(int id) {
-        switch (id) {
-        case DLG_CONFIRM_UNMOUNT:
-                return new AlertDialog.Builder(getActivity())
-                    .setTitle(R.string.dlg_confirm_unmount_title)
-                    .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
-                        public void onClick(DialogInterface dialog, int which) {
-                            doUnmount();
-                        }})
-                    .setNegativeButton(R.string.cancel, null)
-                    .setMessage(R.string.dlg_confirm_unmount_text)
-                    .create();
-        case DLG_ERROR_UNMOUNT:
-                return new AlertDialog.Builder(getActivity())
-            .setTitle(R.string.dlg_error_unmount_title)
-            .setNeutralButton(R.string.dlg_ok, null)
-            .setMessage(R.string.dlg_error_unmount_text)
-            .create();
-        }
-        return null;
-    }
-
-    private void doUnmount() {
-        // Present a toast here
-        Toast.makeText(getActivity(), R.string.unmount_inform_text, Toast.LENGTH_SHORT).show();
-        IMountService mountService = getMountService();
-        try {
-            sLastClickedMountToggle.setEnabled(false);
-            sLastClickedMountToggle.setTitle(getString(R.string.sd_ejecting_title));
-            sLastClickedMountToggle.setSummary(getString(R.string.sd_ejecting_summary));
-            mountService.unmountVolume(sClickedMountPoint, true, false);
-        } catch (RemoteException e) {
-            // Informative dialog to user that unmount failed.
-            showDialogInner(DLG_ERROR_UNMOUNT);
-        }
-    }
-
-    private void showDialogInner(int id) {
-        removeDialog(id);
-        showDialog(id);
-    }
-
-    private boolean hasAppsAccessingStorage() throws RemoteException {
-        IMountService mountService = getMountService();
-        int stUsers[] = mountService.getStorageUsers(sClickedMountPoint);
-        if (stUsers != null && stUsers.length > 0) {
-            return true;
-        }
-        // TODO FIXME Parameterize with mountPoint and uncomment.
-        // On HC-MR2, no apps can be installed on sd and the emulated internal storage is not
-        // removable: application cannot interfere with unmount
-        /*
-        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
-        List<ApplicationInfo> list = am.getRunningExternalApplications();
-        if (list != null && list.size() > 0) {
-            return true;
-        }
-        */
-        // Better safe than sorry. Assume the storage is used to ask for confirmation.
-        return true;
-    }
-
-    private void unmount() {
-        // Check if external media is in use.
-        try {
-           if (hasAppsAccessingStorage()) {
-               // Present dialog to user
-               showDialogInner(DLG_CONFIRM_UNMOUNT);
-           } else {
-               doUnmount();
-           }
-        } catch (RemoteException e) {
-            // Very unlikely. But present an error dialog anyway
-            Log.e(TAG, "Is MountService running?");
-            showDialogInner(DLG_ERROR_UNMOUNT);
-        }
-    }
-
-    private void mount() {
-        IMountService mountService = getMountService();
-        try {
-            if (mountService != null) {
-                mountService.mountVolume(sClickedMountPoint);
-            } else {
-                Log.e(TAG, "Mount service is null, can't mount");
-            }
-        } catch (RemoteException ex) {
-            // Not much can be done
-        }
-    }
-
-    private void onCacheCleared() {
-        for (StorageVolumePreferenceCategory category : mCategories) {
-            category.onCacheCleared();
-        }
-    }
-
-    private static class ClearCacheObserver extends IPackageDataObserver.Stub {
-        private final Memory mTarget;
-        private int mRemaining;
-
-        public ClearCacheObserver(Memory target, int remaining) {
-            mTarget = target;
-            mRemaining = remaining;
-        }
-
-        @Override
-        public void onRemoveCompleted(final String packageName, final boolean succeeded) {
-            synchronized (this) {
-                if (--mRemaining == 0) {
-                    mTarget.onCacheCleared();
-                }
-            }
-        }
-    }
-
-    /**
-     * Dialog to request user confirmation before clearing all cache data.
-     */
-    public static class ConfirmClearCacheFragment extends DialogFragment {
-        public static void show(Memory parent) {
-            if (!parent.isAdded()) return;
-
-            final ConfirmClearCacheFragment dialog = new ConfirmClearCacheFragment();
-            dialog.setTargetFragment(parent, 0);
-            dialog.show(parent.getFragmentManager(), TAG_CONFIRM_CLEAR_CACHE);
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final Context context = getActivity();
-
-            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-            builder.setTitle(R.string.memory_clear_cache_title);
-            builder.setMessage(getString(R.string.memory_clear_cache_message));
-
-            builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    final Memory target = (Memory) getTargetFragment();
-                    final PackageManager pm = context.getPackageManager();
-                    final List<PackageInfo> infos = pm.getInstalledPackages(0);
-                    final ClearCacheObserver observer = new ClearCacheObserver(
-                            target, infos.size());
-                    for (PackageInfo info : infos) {
-                        pm.deleteApplicationCacheFiles(info.packageName, observer);
-                    }
-                }
-            });
-            builder.setNegativeButton(android.R.string.cancel, null);
-
-            return builder.create();
-        }
-    }
-
-    /**
-     * Enable indexing of searchable data
-     */
-    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-        new BaseSearchIndexProvider() {
-            @Override
-            public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
-                final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
-
-                SearchIndexableRaw data = new SearchIndexableRaw(context);
-                data.title = context.getString(R.string.storage_settings);
-                data.screenTitle = context.getString(R.string.storage_settings);
-                result.add(data);
-
-                data = new SearchIndexableRaw(context);
-                data.title = context.getString(R.string.internal_storage);
-                data.screenTitle = context.getString(R.string.storage_settings);
-                result.add(data);
-
-                data = new SearchIndexableRaw(context);
-                final StorageVolume[] storageVolumes = StorageManager.from(context).getVolumeList();
-                for (StorageVolume volume : storageVolumes) {
-                    if (!volume.isEmulated()) {
-                        data.title = volume.getDescription(context);
-                        data.screenTitle = context.getString(R.string.storage_settings);
-                        result.add(data);
-                    }
-                }
-
-                data = new SearchIndexableRaw(context);
-                data.title = context.getString(R.string.memory_size);
-                data.screenTitle = context.getString(R.string.storage_settings);
-                result.add(data);
-
-                data = new SearchIndexableRaw(context);
-                data.title = context.getString(R.string.memory_available);
-                data.screenTitle = context.getString(R.string.storage_settings);
-                result.add(data);
-
-                data = new SearchIndexableRaw(context);
-                data.title = context.getString(R.string.memory_apps_usage);
-                data.screenTitle = context.getString(R.string.storage_settings);
-                result.add(data);
-
-                data = new SearchIndexableRaw(context);
-                data.title = context.getString(R.string.memory_dcim_usage);
-                data.screenTitle = context.getString(R.string.storage_settings);
-                result.add(data);
-
-                data = new SearchIndexableRaw(context);
-                data.title = context.getString(R.string.memory_music_usage);
-                data.screenTitle = context.getString(R.string.storage_settings);
-                result.add(data);
-
-                data = new SearchIndexableRaw(context);
-                data.title = context.getString(R.string.memory_downloads_usage);
-                data.screenTitle = context.getString(R.string.storage_settings);
-                result.add(data);
-
-                data = new SearchIndexableRaw(context);
-                data.title = context.getString(R.string.memory_media_cache_usage);
-                data.screenTitle = context.getString(R.string.storage_settings);
-                result.add(data);
-
-                data = new SearchIndexableRaw(context);
-                data.title = context.getString(R.string.memory_media_misc_usage);
-                data.screenTitle = context.getString(R.string.storage_settings);
-                result.add(data);
-
-                return result;
-            }
-        };
-
-}
diff --git a/src/com/android/settings/deviceinfo/MiscFilesHandler.java b/src/com/android/settings/deviceinfo/MiscFilesHandler.java
deleted file mode 100644
index 93e352b..0000000
--- a/src/com/android/settings/deviceinfo/MiscFilesHandler.java
+++ /dev/null
@@ -1,286 +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.app.Activity;
-import android.app.ListActivity;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.storage.StorageVolume;
-import android.text.format.Formatter;
-import android.util.Log;
-import android.util.SparseBooleanArray;
-import android.view.ActionMode;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnLongClickListener;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.ListView;
-
-import com.android.settings.R;
-import com.android.settings.deviceinfo.StorageMeasurement.FileInfo;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class handles the selection and removal of Misc files.
- */
-public class MiscFilesHandler extends ListActivity {
-    private static final String TAG = "MemorySettings";
-    private String mNumSelectedFormat;
-    private String mNumBytesSelectedFormat;
-    private MemoryMearurementAdapter mAdapter;
-    private LayoutInflater mInflater;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setFinishOnTouchOutside(true);
-        setTitle(R.string.misc_files);
-        mNumSelectedFormat = getString(R.string.misc_files_selected_count);
-        mNumBytesSelectedFormat = getString(R.string.misc_files_selected_count_bytes);
-        mAdapter = new MemoryMearurementAdapter(this);
-        mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        setContentView(R.layout.settings_storage_miscfiles_list);
-        ListView lv = getListView();
-        lv.setItemsCanFocus(true);
-        lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
-        lv.setMultiChoiceModeListener(new ModeCallback(this));
-        setListAdapter(mAdapter);
-    } 
-
-    private class ModeCallback implements ListView.MultiChoiceModeListener {
-        private int mDataCount;
-        private final Context mContext;
-
-        public ModeCallback(Context context) {
-            mContext = context;
-            mDataCount = mAdapter.getCount();
-        }
-
-        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
-            final MenuInflater inflater = getMenuInflater();
-            inflater.inflate(R.menu.misc_files_menu, menu);
-            return true;
-        }
-
-        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
-            return true;
-        }
-
-        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
-            ListView lv = getListView();
-            switch (item.getItemId()) {
-            case R.id.action_delete:
-                // delete the files selected
-                SparseBooleanArray checkedItems = lv.getCheckedItemPositions();
-                int checkedCount = getListView().getCheckedItemCount();
-                if (checkedCount > mDataCount) {
-                    throw new IllegalStateException("checked item counts do not match. " +
-                            "checkedCount: " + checkedCount + ", dataSize: " + mDataCount);
-                }
-                if (mDataCount > 0) {
-                    ArrayList<Object> toRemove = new ArrayList<Object>();
-                    for (int i = 0; i < mDataCount; i++) {
-                        if (!checkedItems.get(i)) {
-                            //item not selected
-                            continue;
-                        }
-                        if (StorageMeasurement.LOGV) {
-                            Log.i(TAG, "deleting: " + mAdapter.getItem(i));
-                        }
-                        // delete the file
-                        File file = new File(mAdapter.getItem(i).mFileName);
-                        if (file.isDirectory()) {
-                            deleteDir(file);
-                        } else {
-                            file.delete();                            
-                        }
-                        toRemove.add(mAdapter.getItem(i));
-                    }
-                    mAdapter.removeAll(toRemove);
-                    mAdapter.notifyDataSetChanged();
-                    mDataCount = mAdapter.getCount();
-                }
-                mode.finish();
-                break;
-
-            case R.id.action_select_all:
-                // check ALL items
-                for (int i = 0; i < mDataCount; i++) {
-                    lv.setItemChecked(i, true);
-                }
-                // update the title and subtitle with number selected and numberBytes selected
-                onItemCheckedStateChanged(mode, 1, 0, true);
-                break;
-            }
-            return true;
-        }
-
-        // Deletes all files and subdirectories under given dir.
-        // Returns true if all deletions were successful.
-        // If a deletion fails, the method stops attempting to delete and returns false.
-        private boolean deleteDir(File dir) {
-            String[] children = dir.list();
-            if (children != null) {
-                for (int i=0; i < children.length; i++) {
-                    boolean success = deleteDir(new File(dir, children[i]));
-                    if (!success) {
-                        return false;
-                    }
-                }
-            }
-            // The directory is now empty so delete it
-            return dir.delete();
-        }
-
-        public void onDestroyActionMode(ActionMode mode) {
-            // This block intentionally left blank
-        }
-
-        public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
-                boolean checked) {
-            ListView lv = getListView();
-            int numChecked = lv.getCheckedItemCount();
-            mode.setTitle(String.format(mNumSelectedFormat, numChecked, mAdapter.getCount()));
-
-            // total the sizes of all items selected so far
-            SparseBooleanArray checkedItems = lv.getCheckedItemPositions();
-            long selectedDataSize = 0;
-            if (numChecked > 0) {
-                for (int i = 0; i < mDataCount; i++) {
-                    if (checkedItems.get(i)) {
-                        // item is checked
-                        selectedDataSize += mAdapter.getItem(i).mSize;
-                    }
-                }
-            }
-            mode.setSubtitle(String.format(mNumBytesSelectedFormat,
-                    Formatter.formatFileSize(mContext, selectedDataSize),
-                    Formatter.formatFileSize(mContext, mAdapter.getDataSize())));
-        }
-    }
-
-    class MemoryMearurementAdapter extends BaseAdapter {
-        private ArrayList<StorageMeasurement.FileInfo> mData = null;
-        private long mDataSize = 0;
-        private Context mContext;
-
-        public MemoryMearurementAdapter(Activity activity) {
-            mContext = activity;
-            final StorageVolume storageVolume = activity.getIntent().getParcelableExtra(
-                    StorageVolume.EXTRA_STORAGE_VOLUME);
-            StorageMeasurement mMeasurement = StorageMeasurement.getInstance(
-                    activity, storageVolume);
-            if (mMeasurement == null) return;
-            mData = (ArrayList<StorageMeasurement.FileInfo>) mMeasurement.mFileInfoForMisc;
-            if (mData != null) {
-                for (StorageMeasurement.FileInfo info : mData) {
-                    mDataSize += info.mSize;
-                }
-            }
-        }
-
-        @Override
-        public int getCount() {
-            return (mData == null) ? 0 : mData.size();
-        }
-
-        @Override
-        public StorageMeasurement.FileInfo getItem(int position) {
-            if (mData == null || mData.size() <= position) {
-                return null;
-            }
-            return mData.get(position);
-        }
-
-        @Override
-        public long getItemId(int position) {
-            if (mData == null || mData.size() <= position) {
-                return 0;
-            }
-            return mData.get(position).mId;
-        }
-
-        public void removeAll(List<Object> objs) {
-            if (mData == null) {
-                return;
-            }
-            for (Object o : objs) {
-                mData.remove(o);
-                mDataSize -= ((StorageMeasurement.FileInfo) o).mSize;
-            }
-        }
-
-        public long getDataSize() {
-            return mDataSize;
-        }
-
-        @Override
-        public void notifyDataSetChanged() {
-            super.notifyDataSetChanged();
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            final FileItemInfoLayout view = (convertView == null) ?
-                    (FileItemInfoLayout) mInflater.inflate(R.layout.settings_storage_miscfiles,
-                            parent, false) : (FileItemInfoLayout) convertView;
-            FileInfo item = getItem(position);
-            view.setFileName(item.mFileName);
-            view.setFileSize(Formatter.formatFileSize(mContext, item.mSize));
-            final ListView listView = (ListView) parent;
-            final int listPosition = position;
-            view.getCheckBox().setOnCheckedChangeListener(new OnCheckedChangeListener() {
-                
-                @Override
-                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-                    listView.setItemChecked(listPosition, isChecked);
-                }
-                
-            });
-            view.setOnLongClickListener(new OnLongClickListener() {
-                @Override
-                public boolean onLongClick(View v) {
-                    if (listView.getCheckedItemCount() > 0) {
-                        return false;
-                    }
-                    listView.setItemChecked(listPosition, !view.isChecked());
-                    return true;
-                }
-            });
-            view.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    if (listView.getCheckedItemCount() > 0) {
-                        listView.setItemChecked(listPosition, !view.isChecked());
-                    }
-                }
-            });
-            return view;
-        }
-    }
-}
diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java
new file mode 100644
index 0000000..efb9a07
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java
@@ -0,0 +1,548 @@
+/*
+ * 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 static com.android.settings.deviceinfo.StorageSettings.EXTRA_VOLUME_ID;
+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.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.storage.StorageEventListener;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.provider.MediaStore;
+import android.text.TextUtils;
+import android.text.format.Formatter;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.EditText;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.util.Preconditions;
+import com.android.settings.R;
+import com.android.settings.Settings;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.deviceinfo.StorageMeasurement.MeasurementDetails;
+import com.android.settings.deviceinfo.StorageMeasurement.MeasurementReceiver;
+import com.android.settings.deviceinfo.StorageSettings.FormatTask;
+import com.android.settings.deviceinfo.StorageSettings.MountTask;
+import com.android.settings.deviceinfo.StorageSettings.UnmountTask;
+import com.google.android.collect.Lists;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Panel showing summary and actions for a {@link VolumeInfo#TYPE_PRIVATE}
+ * storage volume.
+ */
+public class PrivateVolumeSettings extends SettingsPreferenceFragment {
+    // TODO: disable unmount when providing over MTP/PTP
+
+    private static final String TAG_RENAME = "rename";
+    private static final String TAG_CONFIRM_CLEAR_CACHE = "confirmClearCache";
+
+    private StorageManager mStorageManager;
+    private UserManager mUserManager;
+
+    private VolumeInfo mVolume;
+    private VolumeInfo mSharedVolume;
+
+    private StorageMeasurement mMeasure;
+
+    private UserInfo mCurrentUser;
+
+    private int mNextOrder = 0;
+
+    private UsageBarPreference mGraph;
+    private StorageItemPreference mTotal;
+    private StorageItemPreference mAvailable;
+    private StorageItemPreference mApps;
+    private StorageItemPreference mDcim;
+    private StorageItemPreference mMusic;
+    private StorageItemPreference mDownloads;
+    private StorageItemPreference mCache;
+    private StorageItemPreference mMisc;
+    private List<StorageItemPreference> mUsers = Lists.newArrayList();
+
+    private long mTotalSize;
+    private long mAvailSize;
+
+    @Override
+    protected int getMetricsCategory() {
+        return MetricsLogger.DEVICEINFO_STORAGE;
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        final Context context = getActivity();
+
+        mUserManager = context.getSystemService(UserManager.class);
+        mStorageManager = context.getSystemService(StorageManager.class);
+
+        final String volId = getArguments().getString(EXTRA_VOLUME_ID);
+        mVolume = Preconditions.checkNotNull(mStorageManager.findVolumeById(volId));
+        Preconditions.checkState(mVolume.type == VolumeInfo.TYPE_PRIVATE);
+
+        addPreferencesFromResource(R.xml.device_info_storage_volume);
+
+        // Find the emulated shared storage layered above this private volume
+        mSharedVolume = mStorageManager.findVolumeById(
+                mVolume.id.replace("private", "emulated"));
+
+        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);
+
+        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);
+
+        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);
+            mUsers.add(userPref);
+        }
+
+        setHasOptionsMenu(true);
+    }
+
+    public void refresh() {
+        getActivity().setTitle(mStorageManager.getBestVolumeDescription(mVolume.id));
+
+        // Valid options may have changed
+        getFragmentManager().invalidateOptionsMenu();
+
+        final Context context = getActivity();
+        final PreferenceScreen screen = getPreferenceScreen();
+
+        screen.removeAll();
+
+        if (mVolume.state != VolumeInfo.STATE_MOUNTED) {
+            return;
+        }
+
+        screen.addPreference(mGraph);
+        screen.addPreference(mTotal);
+        screen.addPreference(mAvailable);
+
+        final boolean showUsers = !mUsers.isEmpty();
+        if (showUsers) {
+            screen.addPreference(new PreferenceHeader(context, mCurrentUser.name));
+        }
+
+        screen.addPreference(mApps);
+        screen.addPreference(mDcim);
+        screen.addPreference(mMusic);
+        screen.addPreference(mDownloads);
+        screen.addPreference(mCache);
+        screen.addPreference(mMisc);
+
+        if (showUsers) {
+            screen.addPreference(new PreferenceHeader(context, R.string.storage_other_users));
+            for (Preference pref : mUsers) {
+                screen.addPreference(pref);
+            }
+        }
+
+        for (int i = 0; i < screen.getPreferenceCount(); i++) {
+            final Preference pref = screen.getPreference(i);
+            if (pref instanceof StorageItemPreference) {
+                ((StorageItemPreference) pref).setLoading();
+            }
+        }
+
+        final File file = new File(mVolume.path);
+        mTotalSize = file.getTotalSpace();
+        mAvailSize = file.getFreeSpace();
+
+        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();
+
+        mMeasure.forceMeasure();
+    }
+
+    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;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mStorageManager.registerListener(mStorageListener);
+        refresh();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mStorageManager.unregisterListener(mStorageListener);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mMeasure.onDestroy();
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        inflater.inflate(R.menu.storage_volume, menu);
+    }
+
+    @Override
+    public void onPrepareOptionsMenu(Menu menu) {
+        final MenuItem rename = menu.findItem(R.id.storage_rename);
+        final MenuItem mount = menu.findItem(R.id.storage_mount);
+        final MenuItem unmount = menu.findItem(R.id.storage_unmount);
+        final MenuItem format = menu.findItem(R.id.storage_format);
+        final MenuItem usb = menu.findItem(R.id.storage_usb);
+
+        // Actions live in menu for non-internal private volumes; they're shown
+        // as preference items for public volumes.
+        if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(mVolume.id)) {
+            rename.setVisible(false);
+            mount.setVisible(false);
+            unmount.setVisible(false);
+            format.setVisible(false);
+        } else {
+            rename.setVisible(mVolume.type == VolumeInfo.TYPE_PRIVATE);
+            mount.setVisible(mVolume.state == VolumeInfo.STATE_UNMOUNTED);
+            unmount.setVisible(mVolume.state == VolumeInfo.STATE_MOUNTED);
+            format.setVisible(true);
+        }
+
+        // TODO: show usb if we jumped past first screen
+        usb.setVisible(false);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        final Context context = getActivity();
+        switch (item.getItemId()) {
+            case R.id.storage_rename:
+                RenameFragment.show(this);
+                return true;
+            case R.id.storage_mount:
+                new MountTask(context, mVolume.id).execute();
+                return true;
+            case R.id.storage_unmount:
+                new UnmountTask(context, mVolume.id).execute();
+                return true;
+            case R.id.storage_format:
+                new FormatTask(context, mVolume.id).execute();
+                return true;
+            case R.id.storage_usb:
+                startFragment(this, UsbSettings.class.getCanonicalName(),
+                        R.string.storage_title_usb, 0, null);
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference pref) {
+        // TODO: launch better intents for specific volume
+
+        Intent intent = null;
+        if (pref == mApps) {
+            intent = new Intent(Intent.ACTION_MANAGE_PACKAGE_STORAGE);
+            intent.setClass(getActivity(), Settings.ManageApplicationsActivity.class);
+
+        } 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 == 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 == mCache) {
+            ConfirmClearCacheFragment.show(this);
+            return true;
+
+        } else if (pref == mMisc) {
+            intent = StorageSettings.buildBrowseIntent(mSharedVolume);
+        }
+
+        if (intent != null) {
+            try {
+                startActivity(intent);
+            } catch (ActivityNotFoundException e) {
+                Log.w(TAG, "No activity found for " + intent);
+            }
+            return true;
+        }
+        return super.onPreferenceTreeClick(preferenceScreen, pref);
+    }
+
+    private final MeasurementReceiver mReceiver = new MeasurementReceiver() {
+        @Override
+        public void onDetailsChanged(MeasurementDetails details) {
+            updateDetails(details);
+        }
+    };
+
+    private void updateDetails(MeasurementDetails details) {
+        mGraph.clear();
+
+        updatePreference(mApps, details.appsSize);
+
+        final long dcimSize = totalValues(details.mediaSize, Environment.DIRECTORY_DCIM,
+                Environment.DIRECTORY_MOVIES, Environment.DIRECTORY_PICTURES);
+        updatePreference(mDcim, dcimSize);
+
+        final long musicSize = 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(mCache, details.cacheSize);
+        updatePreference(mMisc, 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);
+        }
+    }
+
+    /**
+     * Return list of other users, excluding the current user.
+     */
+    private List<UserInfo> getUsersExcluding(UserInfo excluding) {
+        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) {
+        long total = 0;
+        for (String key : keys) {
+            if (map.containsKey(key)) {
+                total += map.get(key);
+            }
+        }
+        return total;
+    }
+
+    private final StorageEventListener mStorageListener = new StorageEventListener() {
+        @Override
+        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
+            if (Objects.equals(mVolume.id, vol.id)) {
+                mVolume = vol;
+                refresh();
+            }
+        }
+    };
+
+    /**
+     * Dialog that allows editing of volume nickname.
+     */
+    public static class RenameFragment extends DialogFragment {
+        public static void show(PrivateVolumeSettings parent) {
+            if (!parent.isAdded()) return;
+
+            final RenameFragment dialog = new RenameFragment();
+            dialog.setTargetFragment(parent, 0);
+            dialog.setArguments(parent.getArguments());
+            dialog.show(parent.getFragmentManager(), TAG_RENAME);
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            final Context context = getActivity();
+            final StorageManager storageManager = context.getSystemService(StorageManager.class);
+
+            final String volId = getArguments().getString(EXTRA_VOLUME_ID);
+            final VolumeInfo vol = storageManager.findVolumeById(volId);
+
+            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+            final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
+
+            final View view = dialogInflater.inflate(R.layout.dialog_edittext, null, false);
+            final EditText nickname = (EditText) view.findViewById(R.id.edittext);
+
+            if (!TextUtils.isEmpty(vol.nickname)) {
+                nickname.setText(vol.nickname);
+            } else {
+                nickname.setText(storageManager.getBestVolumeDescription(volId));
+            }
+
+            builder.setTitle(R.string.storage_rename_title);
+            builder.setView(view);
+
+            builder.setPositiveButton(R.string.save,
+                    new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            // TODO: persist the edited nickname!
+                        }
+                    });
+            builder.setNegativeButton(R.string.cancel, 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) {
+            if (!parent.isAdded()) return;
+
+            final ConfirmClearCacheFragment dialog = new ConfirmClearCacheFragment();
+            dialog.setTargetFragment(parent, 0);
+            dialog.show(parent.getFragmentManager(), TAG_CONFIRM_CLEAR_CACHE);
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            final Context context = getActivity();
+
+            final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+            builder.setTitle(R.string.memory_clear_cache_title);
+            builder.setMessage(getString(R.string.memory_clear_cache_message));
+
+            builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                @Override
+                public void onClick(DialogInterface dialog, int which) {
+                    final PrivateVolumeSettings target = (PrivateVolumeSettings) getTargetFragment();
+                    final PackageManager pm = context.getPackageManager();
+                    final List<PackageInfo> infos = pm.getInstalledPackages(0);
+                    final ClearCacheObserver observer = new ClearCacheObserver(
+                            target, infos.size());
+                    for (PackageInfo info : infos) {
+                        pm.deleteApplicationCacheFiles(info.packageName, observer);
+                    }
+                }
+            });
+            builder.setNegativeButton(android.R.string.cancel, null);
+
+            return builder.create();
+        }
+    }
+
+    private static class ClearCacheObserver extends IPackageDataObserver.Stub {
+        private final PrivateVolumeSettings mTarget;
+        private int mRemaining;
+
+        public ClearCacheObserver(PrivateVolumeSettings target, int remaining) {
+            mTarget = target;
+            mRemaining = remaining;
+        }
+
+        @Override
+        public void onRemoveCompleted(final String packageName, final boolean succeeded) {
+            synchronized (this) {
+                if (--mRemaining == 0) {
+                    mTarget.refresh();
+                }
+            }
+        }
+    }
+
+    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;
+        }
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/PublicVolumeSettings.java b/src/com/android/settings/deviceinfo/PublicVolumeSettings.java
new file mode 100644
index 0000000..6edfc92
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/PublicVolumeSettings.java
@@ -0,0 +1,205 @@
+/*
+ * 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 static com.android.settings.deviceinfo.StorageSettings.EXTRA_VOLUME_ID;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.SystemProperties;
+import android.os.storage.StorageEventListener;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.provider.DocumentsContract;
+import android.text.format.Formatter;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.util.Preconditions;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.deviceinfo.StorageSettings.FormatTask;
+import com.android.settings.deviceinfo.StorageSettings.MountTask;
+import com.android.settings.deviceinfo.StorageSettings.UnmountTask;
+
+import java.io.File;
+import java.util.Objects;
+
+/**
+ * Panel showing summary and actions for a {@link VolumeInfo#TYPE_PUBLIC}
+ * storage volume.
+ */
+public class PublicVolumeSettings extends SettingsPreferenceFragment {
+    // TODO: disable unmount when providing over MTP/PTP
+
+    private static final String PREF_FORMAT_INTERNAL = "debug.format_internal";
+
+    private StorageManager mStorageManager;
+
+    private VolumeInfo mVolume;
+
+    private int mNextOrder = 0;
+
+    private UsageBarPreference mGraph;
+    private StorageItemPreference mTotal;
+    private StorageItemPreference mAvailable;
+
+    private Preference mMount;
+    private Preference mUnmount;
+    private Preference mFormat;
+    private Preference mFormatInternal;
+
+    private long mTotalSize;
+    private long mAvailSize;
+
+    @Override
+    protected int getMetricsCategory() {
+        return MetricsLogger.DEVICEINFO_STORAGE;
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        final Context context = getActivity();
+
+        mStorageManager = context.getSystemService(StorageManager.class);
+
+        if (DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS.equals(
+                getActivity().getIntent().getAction())) {
+            final Uri rootUri = getActivity().getIntent().getData();
+            final String fsUuid = DocumentsContract.getRootId(rootUri);
+            mVolume = mStorageManager.findVolumeByUuid(fsUuid);
+        } else {
+            final String volId = getArguments().getString(EXTRA_VOLUME_ID);
+            mVolume = mStorageManager.findVolumeById(volId);
+        }
+
+        Preconditions.checkNotNull(mVolume);
+        Preconditions.checkState(mVolume.type == VolumeInfo.TYPE_PUBLIC);
+
+        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);
+
+        mMount = buildAction(R.string.storage_menu_mount);
+        mUnmount = buildAction(R.string.storage_menu_unmount);
+        mFormat = buildAction(R.string.storage_menu_format);
+        mFormatInternal = buildAction(R.string.storage_menu_format_internal);
+    }
+
+    public void refresh() {
+        getActivity().setTitle(mStorageManager.getBestVolumeDescription(mVolume.id));
+
+        final Context context = getActivity();
+        final PreferenceScreen screen = getPreferenceScreen();
+
+        screen.removeAll();
+
+        if (mVolume.state == VolumeInfo.STATE_MOUNTED) {
+            screen.addPreference(mGraph);
+            screen.addPreference(mTotal);
+            screen.addPreference(mAvailable);
+        }
+
+        if (mVolume.state == VolumeInfo.STATE_UNMOUNTED) {
+            screen.addPreference(mMount);
+        }
+        if (mVolume.state == VolumeInfo.STATE_MOUNTED) {
+            screen.addPreference(mUnmount);
+        }
+        screen.addPreference(mFormat);
+        if (SystemProperties.getBoolean(PREF_FORMAT_INTERNAL, false)) {
+            screen.addPreference(mFormatInternal);
+        }
+
+        final File file = new File(mVolume.path);
+        mTotalSize = file.getTotalSpace();
+        mAvailSize = file.getFreeSpace();
+
+        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();
+    }
+
+    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);
+        pref.setOrder(mNextOrder++);
+        return pref;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mStorageManager.registerListener(mStorageListener);
+        refresh();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mStorageManager.unregisterListener(mStorageListener);
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference pref) {
+        final Context context = getActivity();
+        if (pref == mMount) {
+            new MountTask(context, mVolume.id).execute();
+        } else if (pref == mUnmount) {
+            new UnmountTask(context, mVolume.id).execute();
+        } else if (pref == mFormat) {
+            new FormatTask(context, mVolume.id).execute();
+        } else if (pref == mFormatInternal) {
+            // TODO: implement this
+        }
+
+        return super.onPreferenceTreeClick(preferenceScreen, pref);
+    }
+
+    private final StorageEventListener mStorageListener = new StorageEventListener() {
+        @Override
+        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
+            if (Objects.equals(mVolume.id, vol.id)) {
+                mVolume = vol;
+                refresh();
+            }
+        }
+    };
+}
diff --git a/src/com/android/settings/deviceinfo/StorageItemPreference.java b/src/com/android/settings/deviceinfo/StorageItemPreference.java
index 87e827e..8d48cf0 100644
--- a/src/com/android/settings/deviceinfo/StorageItemPreference.java
+++ b/src/com/android/settings/deviceinfo/StorageItemPreference.java
@@ -62,4 +62,8 @@
         shape.getPaint().setColor(color);
         return shape;
     }
+
+    public void setLoading() {
+        setSummary(R.string.memory_calculating_size);
+    }
 }
diff --git a/src/com/android/settings/deviceinfo/StorageMeasurement.java b/src/com/android/settings/deviceinfo/StorageMeasurement.java
index 34ef62b..db91fdb 100644
--- a/src/com/android/settings/deviceinfo/StorageMeasurement.java
+++ b/src/com/android/settings/deviceinfo/StorageMeasurement.java
@@ -27,7 +27,6 @@
 import android.content.pm.PackageStats;
 import android.content.pm.UserInfo;
 import android.os.Environment;
-import android.os.Environment.UserEnvironment;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
@@ -36,23 +35,22 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageVolume;
+import android.os.storage.VolumeInfo;
 import android.util.Log;
 import android.util.SparseLongArray;
 
 import com.android.internal.app.IMediaContainerService;
-import com.google.android.collect.Maps;
+import com.android.internal.util.ArrayUtils;
 import com.google.android.collect.Sets;
 
 import java.io.File;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
-import javax.annotation.concurrent.GuardedBy;
-
 /**
  * Utility for measuring the disk usage of internal storage or a physical
  * {@link StorageVolume}. Connects with a remote {@link IMediaContainerService}
@@ -77,28 +75,7 @@
             Environment.DIRECTORY_RINGTONES, Environment.DIRECTORY_PODCASTS,
             Environment.DIRECTORY_DOWNLOADS, Environment.DIRECTORY_ANDROID);
 
-    @GuardedBy("sInstances")
-    private static HashMap<StorageVolume, StorageMeasurement> sInstances = Maps.newHashMap();
-
-    /**
-     * Obtain shared instance of {@link StorageMeasurement} for given physical
-     * {@link StorageVolume}, or internal storage if {@code null}.
-     */
-    public static StorageMeasurement getInstance(Context context, StorageVolume volume) {
-        synchronized (sInstances) {
-            StorageMeasurement value = sInstances.get(volume);
-            if (value == null) {
-                value = new StorageMeasurement(context.getApplicationContext(), volume);
-                sInstances.put(volume, value);
-            }
-            return value;
-        }
-    }
-
     public static class MeasurementDetails {
-        public long totalSize;
-        public long availSize;
-
         /**
          * Total apps disk usage.
          * <p>
@@ -128,7 +105,7 @@
          * When measuring a physical {@link StorageVolume}, this reflects media
          * on that volume.
          */
-        public HashMap<String, Long> mediaSize = Maps.newHashMap();
+        public HashMap<String, Long> mediaSize = new HashMap<>();
 
         /**
          * Misc external disk usage for the current user, unaccounted in
@@ -144,34 +121,31 @@
     }
 
     public interface MeasurementReceiver {
-        public void updateApproximate(StorageMeasurement meas, long totalSize, long availSize);
-        public void updateDetails(StorageMeasurement meas, MeasurementDetails details);
+        public void onDetailsChanged(MeasurementDetails details);
     }
 
-    private volatile WeakReference<MeasurementReceiver> mReceiver;
+    private WeakReference<MeasurementReceiver> mReceiver;
 
-    /** Physical volume being measured, or {@code null} for internal. */
-    private final StorageVolume mVolume;
+    private final Context mContext;
 
-    private final boolean mIsInternal;
-    private final boolean mIsPrimary;
+    private final VolumeInfo mVolume;
+    private final VolumeInfo mSharedVolume;
 
-    private final MeasurementHandler mHandler;
+    private final MainHandler mMainHandler;
+    private final MeasurementHandler mMeasurementHandler;
 
-    private long mTotalSize;
-    private long mAvailSize;
+    public StorageMeasurement(Context context, VolumeInfo volume, VolumeInfo sharedVolume) {
+        mContext = context.getApplicationContext();
 
-    List<FileInfo> mFileInfoForMisc;
-
-    private StorageMeasurement(Context context, StorageVolume volume) {
         mVolume = volume;
-        mIsInternal = volume == null;
-        mIsPrimary = volume != null ? volume.isPrimary() : false;
+        mSharedVolume = sharedVolume;
 
         // Start the thread that will measure the disk usage.
         final HandlerThread handlerThread = new HandlerThread("MemoryMeasurement");
         handlerThread.start();
-        mHandler = new MeasurementHandler(context, handlerThread.getLooper());
+
+        mMainHandler = new MainHandler();
+        mMeasurementHandler = new MeasurementHandler(handlerThread.getLooper());
     }
 
     public void setReceiver(MeasurementReceiver receiver) {
@@ -180,52 +154,38 @@
         }
     }
 
+    public void forceMeasure() {
+        invalidate();
+        measure();
+    }
+
     public void measure() {
-        if (!mHandler.hasMessages(MeasurementHandler.MSG_MEASURE)) {
-            mHandler.sendEmptyMessage(MeasurementHandler.MSG_MEASURE);
+        if (!mMeasurementHandler.hasMessages(MeasurementHandler.MSG_MEASURE)) {
+            mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_MEASURE);
         }
     }
 
-    public void cleanUp() {
+    public void onDestroy() {
         mReceiver = null;
-        mHandler.removeMessages(MeasurementHandler.MSG_MEASURE);
-        mHandler.sendEmptyMessage(MeasurementHandler.MSG_DISCONNECT);
+        mMeasurementHandler.removeMessages(MeasurementHandler.MSG_MEASURE);
+        mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_DISCONNECT);
     }
 
-    public void invalidate() {
-        mHandler.sendEmptyMessage(MeasurementHandler.MSG_INVALIDATE);
-    }
-
-    private void sendInternalApproximateUpdate() {
-        MeasurementReceiver receiver = (mReceiver != null) ? mReceiver.get() : null;
-        if (receiver == null) {
-            return;
-        }
-        receiver.updateApproximate(this, mTotalSize, mAvailSize);
-    }
-
-    private void sendExactUpdate(MeasurementDetails details) {
-        MeasurementReceiver receiver = (mReceiver != null) ? mReceiver.get() : null;
-        if (receiver == null) {
-            if (LOGV) {
-                Log.i(TAG, "measurements dropped because receiver is null! wasted effort");
-            }
-            return;
-        }
-        receiver.updateDetails(this, details);
+    private void invalidate() {
+        mMeasurementHandler.sendEmptyMessage(MeasurementHandler.MSG_INVALIDATE);
     }
 
     private static class StatsObserver extends IPackageStatsObserver.Stub {
-        private final boolean mIsInternal;
+        private final boolean mIsPrivate;
         private final MeasurementDetails mDetails;
         private final int mCurrentUser;
         private final Message mFinished;
 
         private int mRemaining;
 
-        public StatsObserver(boolean isInternal, MeasurementDetails details, int currentUser,
+        public StatsObserver(boolean isPrivate, MeasurementDetails details, int currentUser,
                 Message finished, int remaining) {
-            mIsInternal = isInternal;
+            mIsPrivate = isPrivate;
             mDetails = details;
             mCurrentUser = currentUser;
             mFinished = finished;
@@ -245,7 +205,7 @@
         }
 
         private void addStatsLocked(PackageStats stats) {
-            if (mIsInternal) {
+            if (mIsPrivate) {
                 long codeSize = stats.codeSize;
                 long dataSize = stats.dataSize;
                 long cacheSize = stats.cacheSize;
@@ -279,6 +239,17 @@
         }
     }
 
+    private class MainHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            final MeasurementDetails details = (MeasurementDetails) msg.obj;
+            final MeasurementReceiver receiver = (mReceiver != null) ? mReceiver.get() : null;
+            if (receiver != null) {
+                receiver.onDetailsChanged(details);
+            }
+        }
+    }
+
     private class MeasurementHandler extends Handler {
         public static final int MSG_MEASURE = 1;
         public static final int MSG_CONNECTED = 2;
@@ -294,8 +265,6 @@
 
         private MeasurementDetails mCached;
 
-        private final WeakReference<Context> mContext;
-
         private final ServiceConnection mDefContainerConn = new ServiceConnection() {
             @Override
             public void onServiceConnected(ComponentName name, IBinder service) {
@@ -313,9 +282,8 @@
             }
         };
 
-        public MeasurementHandler(Context context, Looper looper) {
+        public MeasurementHandler(Looper looper) {
             super(looper);
-            mContext = new WeakReference<Context>(context);
         }
 
         @Override
@@ -323,50 +291,39 @@
             switch (msg.what) {
                 case MSG_MEASURE: {
                     if (mCached != null) {
-                        sendExactUpdate(mCached);
+                        mMainHandler.obtainMessage(0, mCached).sendToTarget();
                         break;
                     }
 
-                    final Context context = (mContext != null) ? mContext.get() : null;
-                    if (context == null) {
-                        return;
-                    }
-
                     synchronized (mLock) {
                         if (mBound) {
                             removeMessages(MSG_DISCONNECT);
                             sendMessage(obtainMessage(MSG_CONNECTED, mDefaultContainer));
                         } else {
                             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
-                            context.bindServiceAsUser(service, mDefContainerConn, Context.BIND_AUTO_CREATE,
-                                    UserHandle.OWNER);
+                            mContext.bindServiceAsUser(service, mDefContainerConn,
+                                    Context.BIND_AUTO_CREATE, UserHandle.OWNER);
                         }
                     }
                     break;
                 }
                 case MSG_CONNECTED: {
-                    IMediaContainerService imcs = (IMediaContainerService) msg.obj;
-                    measureApproximateStorage(imcs);
+                    final IMediaContainerService imcs = (IMediaContainerService) msg.obj;
                     measureExactStorage(imcs);
                     break;
                 }
                 case MSG_DISCONNECT: {
                     synchronized (mLock) {
                         if (mBound) {
-                            final Context context = (mContext != null) ? mContext.get() : null;
-                            if (context == null) {
-                                return;
-                            }
-
                             mBound = false;
-                            context.unbindService(mDefContainerConn);
+                            mContext.unbindService(mDefContainerConn);
                         }
                     }
                     break;
                 }
                 case MSG_COMPLETED: {
                     mCached = (MeasurementDetails) msg.obj;
-                    sendExactUpdate(mCached);
+                    mMainHandler.obtainMessage(0, mCached).sendToTarget();
                     break;
                 }
                 case MSG_INVALIDATE: {
@@ -375,88 +332,75 @@
                 }
             }
         }
+    }
 
-        private void measureApproximateStorage(IMediaContainerService imcs) {
-            final String path = mVolume != null ? mVolume.getPath()
-                    : Environment.getDataDirectory().getPath();
-            try {
-                final long[] stats = imcs.getFileSystemStats(path);
-                mTotalSize = stats[0];
-                mAvailSize = stats[1];
-            } catch (Exception e) {
-                Log.w(TAG, "Problem in container service", e);
-            }
+    private void measureExactStorage(IMediaContainerService imcs) {
+        final UserManager userManager = mContext.getSystemService(UserManager.class);
+        final PackageManager packageManager = mContext.getPackageManager();
 
-            sendInternalApproximateUpdate();
-        }
+        final List<UserInfo> users = userManager.getUsers();
+        final int currentUser = ActivityManager.getCurrentUser();
 
-        private void measureExactStorage(IMediaContainerService imcs) {
-            final Context context = mContext != null ? mContext.get() : null;
-            if (context == null) {
-                return;
-            }
+        final MeasurementDetails details = new MeasurementDetails();
+        final Message finished = mMeasurementHandler.obtainMessage(MeasurementHandler.MSG_COMPLETED,
+                details);
 
-            final MeasurementDetails details = new MeasurementDetails();
-            final Message finished = obtainMessage(MSG_COMPLETED, details);
-
-            details.totalSize = mTotalSize;
-            details.availSize = mAvailSize;
-
-            final UserManager userManager = (UserManager) context.getSystemService(
-                    Context.USER_SERVICE);
-            final List<UserInfo> users = userManager.getUsers();
-
-            final int currentUser = ActivityManager.getCurrentUser();
-            final UserEnvironment currentEnv = new UserEnvironment(currentUser);
+        if (mSharedVolume != null && mSharedVolume.state == VolumeInfo.STATE_MOUNTED) {
+            final File basePath = mSharedVolume.getPathForUser(currentUser);
 
             // Measure media types for emulated storage, or for primary physical
             // external volume
-            final boolean measureMedia = (mIsInternal && Environment.isExternalStorageEmulated())
-                    || mIsPrimary;
-            if (measureMedia) {
-                for (String type : sMeasureMediaTypes) {
-                    final File path = currentEnv.getExternalStoragePublicDirectory(type);
-                    final long size = getDirectorySize(imcs, path);
-                    details.mediaSize.put(type, size);
-                }
+            for (String type : sMeasureMediaTypes) {
+                final File path = new File(basePath, type);
+                final long size = getDirectorySize(imcs, path);
+                details.mediaSize.put(type, size);
             }
 
             // Measure misc files not counted under media
-            if (measureMedia) {
-                final File path = mIsInternal ? currentEnv.getExternalStorageDirectory()
-                        : mVolume.getPathFile();
-                details.miscSize = measureMisc(imcs, path);
-            }
+            details.miscSize = measureMisc(imcs, basePath);
 
-            // Measure total emulated storage of all users; internal apps data
-            // will be spliced in later
-            for (UserInfo user : users) {
-                final UserEnvironment userEnv = new UserEnvironment(user.id);
-                final long size = getDirectorySize(imcs, userEnv.getExternalStorageDirectory());
-                addValue(details.usersSize, user.id, size);
-            }
-
-            // Measure all apps for all users
-            final PackageManager pm = context.getPackageManager();
-            if (mIsInternal || mIsPrimary) {
-                final List<ApplicationInfo> apps = pm.getInstalledApplications(
-                        PackageManager.GET_UNINSTALLED_PACKAGES
-                        | PackageManager.GET_DISABLED_COMPONENTS);
-
-                final int count = users.size() * apps.size();
-                final StatsObserver observer = new StatsObserver(
-                        mIsInternal, details, currentUser, finished, count);
-
+            if (mSharedVolume.type == VolumeInfo.TYPE_EMULATED) {
+                // Measure total emulated storage of all users; internal apps data
+                // will be spliced in later
                 for (UserInfo user : users) {
-                    for (ApplicationInfo app : apps) {
-                        pm.getPackageSizeInfo(app.packageName, user.id, observer);
-                    }
+                    final File userPath = mSharedVolume.getPathForUser(user.id);
+                    final long size = getDirectorySize(imcs, userPath);
+                    addValue(details.usersSize, user.id, size);
                 }
-
-            } else {
-                finished.sendToTarget();
             }
         }
+
+        // Measure all apps hosted on this volume for all users
+        if (mVolume.type == VolumeInfo.TYPE_PRIVATE) {
+            final List<ApplicationInfo> apps = packageManager.getInstalledApplications(
+                    PackageManager.GET_UNINSTALLED_PACKAGES
+                    | PackageManager.GET_DISABLED_COMPONENTS);
+
+            final List<ApplicationInfo> volumeApps = new ArrayList<>();
+            for (ApplicationInfo app : apps) {
+                if (Objects.equals(app.volumeUuid, mVolume.fsUuid)) {
+                    volumeApps.add(app);
+                }
+            }
+
+            final int count = users.size() * volumeApps.size();
+            if (count == 0) {
+                finished.sendToTarget();
+                return;
+            }
+
+            final StatsObserver observer = new StatsObserver(
+                    true, details, currentUser, finished, count);
+            for (UserInfo user : users) {
+                for (ApplicationInfo app : volumeApps) {
+                    packageManager.getPackageSizeInfo(app.packageName, user.id, observer);
+                }
+            }
+
+        } else {
+            finished.sendToTarget();
+            return;
+        }
     }
 
     private static long getDirectorySize(IMediaContainerService imcs, File path) {
@@ -471,64 +415,26 @@
     }
 
     private long measureMisc(IMediaContainerService imcs, File dir) {
-        mFileInfoForMisc = new ArrayList<FileInfo>();
-
         final File[] files = dir.listFiles();
-        if (files == null) return 0;
+        if (ArrayUtils.isEmpty(files)) return 0;
 
         // Get sizes of all top level nodes except the ones already computed
-        long counter = 0;
         long miscSize = 0;
-
         for (File file : files) {
-            final String path = file.getAbsolutePath();
             final String name = file.getName();
             if (sMeasureMediaTypes.contains(name)) {
                 continue;
             }
 
             if (file.isFile()) {
-                final long fileSize = file.length();
-                mFileInfoForMisc.add(new FileInfo(path, fileSize, counter++));
-                miscSize += fileSize;
+                miscSize += file.length();
             } else if (file.isDirectory()) {
-                final long dirSize = getDirectorySize(imcs, file);
-                mFileInfoForMisc.add(new FileInfo(path, dirSize, counter++));
-                miscSize += dirSize;
-            } else {
-                // Non directory, non file: not listed
+                miscSize += getDirectorySize(imcs, file);
             }
         }
-
-        // sort the list of FileInfo objects collected above in descending order of their sizes
-        Collections.sort(mFileInfoForMisc);
-
         return miscSize;
     }
 
-    static class FileInfo implements Comparable<FileInfo> {
-        final String mFileName;
-        final long mSize;
-        final long mId;
-
-        FileInfo(String fileName, long size, long id) {
-            mFileName = fileName;
-            mSize = size;
-            mId = id;
-        }
-
-        @Override
-        public int compareTo(FileInfo that) {
-            if (this == that || mSize == that.mSize) return 0;
-            else return (mSize < that.mSize) ? 1 : -1; // for descending sort
-        }
-
-        @Override
-        public String toString() {
-            return mFileName  + " : " + mSize + ", id:" + mId;
-        }
-    }
-
     private static void addValue(SparseLongArray array, int key, long value) {
         array.put(key, array.get(key) + value);
     }
diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java
new file mode 100644
index 0000000..001f00d
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/StorageSettings.java
@@ -0,0 +1,421 @@
+/*
+ * 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.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.os.storage.StorageEventListener;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.provider.DocumentsContract;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.Toast;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settings.search.SearchIndexableRaw;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Panel showing both internal storage (both built-in storage and private
+ * volumes) and removable storage (public volumes).
+ */
+public class StorageSettings extends SettingsPreferenceFragment implements Indexable {
+    static final String TAG = "StorageSettings";
+
+    // TODO: badging to indicate devices running low on storage
+    // TODO: show currently ejected private volumes
+
+    public static final String EXTRA_VOLUME_ID = "volume_id";
+
+    private static final String DOCUMENT_AUTHORITY = "com.android.externalstorage.documents";
+    private static final String DOCUMENT_ROOT_PRIMARY_EMULATED = "primary";
+
+    /**
+     * Build an intent to browse the contents of given {@link VolumeInfo}.
+     */
+    public static Intent buildBrowseIntent(VolumeInfo vol) {
+        final Uri uri;
+        if (vol.type == VolumeInfo.TYPE_PUBLIC) {
+            uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY, vol.fsUuid);
+        } else if (VolumeInfo.ID_EMULATED_INTERNAL.equals(vol.id)) {
+            uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY,
+                    DOCUMENT_ROOT_PRIMARY_EMULATED);
+        } else if (vol.type == VolumeInfo.TYPE_EMULATED) {
+            // TODO: build intent once supported
+            uri = null;
+        } else {
+            throw new IllegalArgumentException();
+        }
+
+        final Intent intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
+        intent.addCategory(Intent.CATEGORY_DEFAULT);
+        intent.setData(uri);
+        return intent;
+    }
+
+    private UserManager mUserManager;
+    private StorageManager mStorageManager;
+
+    private PreferenceCategory mInternalCategory;
+    private PreferenceCategory mExternalCategory;
+
+    @Override
+    protected int getMetricsCategory() {
+        return MetricsLogger.DEVICEINFO_STORAGE;
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        final Context context = getActivity();
+
+        mUserManager = context.getSystemService(UserManager.class);
+
+        mStorageManager = context.getSystemService(StorageManager.class);
+        mStorageManager.registerListener(mStorageListener);
+
+        addPreferencesFromResource(R.xml.device_info_storage);
+
+        mInternalCategory = (PreferenceCategory) findPreference("storage_internal");
+        mExternalCategory = (PreferenceCategory) findPreference("storage_external");
+
+        // TODO: if only one volume visible, shortcut into it
+
+        setHasOptionsMenu(true);
+    }
+
+    private static final Comparator<VolumeInfo> sVolumeComparator = new Comparator<VolumeInfo>() {
+        @Override
+        public int compare(VolumeInfo lhs, VolumeInfo rhs) {
+            if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(lhs.id)) {
+                return -1;
+            } else if (lhs.getDescription() == null) {
+                return 1;
+            } else {
+                return lhs.getDescription().compareTo(rhs.getDescription());
+            }
+        }
+    };
+
+    private final StorageEventListener mStorageListener = new StorageEventListener() {
+        @Override
+        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
+            if (isInteresting(vol)) {
+                refresh();
+            }
+        }
+    };
+
+    private static boolean isInteresting(VolumeInfo vol) {
+        return vol.type == VolumeInfo.TYPE_PRIVATE || vol.type == VolumeInfo.TYPE_PUBLIC;
+    }
+
+    private void refresh() {
+        final Context context = getActivity();
+
+        getPreferenceScreen().removeAll();
+        mInternalCategory.removeAll();
+        mExternalCategory.removeAll();
+
+        final List<VolumeInfo> volumes = mStorageManager.getVolumes();
+        Collections.sort(volumes, sVolumeComparator);
+
+        for (VolumeInfo vol : volumes) {
+            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
+                mInternalCategory.addPreference(new StorageVolumePreference(context, vol));
+            } else if (vol.type == VolumeInfo.TYPE_PUBLIC) {
+                mExternalCategory.addPreference(new StorageVolumePreference(context, vol));
+            }
+        }
+
+        if (mInternalCategory.getPreferenceCount() > 0) {
+            getPreferenceScreen().addPreference(mInternalCategory);
+        }
+        if (mExternalCategory.getPreferenceCount() > 0) {
+            getPreferenceScreen().addPreference(mExternalCategory);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mStorageManager.registerListener(mStorageListener);
+        refresh();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mStorageManager.unregisterListener(mStorageListener);
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        inflater.inflate(R.menu.storage, menu);
+    }
+
+    @Override
+    public void onPrepareOptionsMenu(Menu menu) {
+        final MenuItem usb = menu.findItem(R.id.storage_usb);
+
+        usb.setVisible(!mUserManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER));
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.storage_usb:
+                startFragment(this, UsbSettings.class.getCanonicalName(),
+                        R.string.storage_title_usb, 0, null);
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference pref) {
+        final String volId = pref.getKey();
+        final VolumeInfo vol = mStorageManager.findVolumeById(volId);
+        if (vol == null) {
+            return false;
+
+        } else if (vol.type == VolumeInfo.TYPE_PRIVATE) {
+            final Bundle args = new Bundle();
+            args.putString(EXTRA_VOLUME_ID, volId);
+            startFragment(this, PrivateVolumeSettings.class.getCanonicalName(),
+                    -1, 0, args);
+            return true;
+
+        } else if (vol.type == VolumeInfo.TYPE_PUBLIC) {
+            if (vol.state == VolumeInfo.STATE_MOUNTED) {
+                final Intent intent = buildBrowseIntent(vol);
+                startActivity(intent);
+                return true;
+            } else {
+                final Bundle args = new Bundle();
+                args.putString(EXTRA_VOLUME_ID, volId);
+                startFragment(this, PublicVolumeSettings.class.getCanonicalName(),
+                        -1, 0, args);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public static class MountTask extends AsyncTask<Void, Void, Exception> {
+        private final Context mContext;
+        private final StorageManager mStorageManager;
+        private final String mVolumeId;
+        private final String mDescription;
+
+        public MountTask(Context context, String volumeId) {
+            mContext = context.getApplicationContext();
+            mStorageManager = mContext.getSystemService(StorageManager.class);
+            mVolumeId = volumeId;
+            mDescription = mStorageManager.getBestVolumeDescription(mVolumeId);
+        }
+
+        @Override
+        protected Exception doInBackground(Void... params) {
+            try {
+                mStorageManager.mount(mVolumeId);
+                return null;
+            } catch (Exception e) {
+                return e;
+            }
+        }
+
+        @Override
+        protected void onPostExecute(Exception e) {
+            if (e == null) {
+                Toast.makeText(mContext, mContext.getString(R.string.storage_mount_success,
+                        mDescription), Toast.LENGTH_SHORT).show();
+            } else {
+                Log.e(TAG, "Failed to mount " + mVolumeId, e);
+                Toast.makeText(mContext, mContext.getString(R.string.storage_mount_failure,
+                        mDescription), Toast.LENGTH_SHORT).show();
+            }
+        }
+    }
+
+    public static class UnmountTask extends AsyncTask<Void, Void, Exception> {
+        private final Context mContext;
+        private final StorageManager mStorageManager;
+        private final String mVolumeId;
+        private final String mDescription;
+
+        public UnmountTask(Context context, String volumeId) {
+            mContext = context.getApplicationContext();
+            mStorageManager = mContext.getSystemService(StorageManager.class);
+            mVolumeId = volumeId;
+            mDescription = mStorageManager.getBestVolumeDescription(mVolumeId);
+        }
+
+        @Override
+        protected Exception doInBackground(Void... params) {
+            try {
+                mStorageManager.unmount(mVolumeId);
+                return null;
+            } catch (Exception e) {
+                return e;
+            }
+        }
+
+        @Override
+        protected void onPostExecute(Exception e) {
+            if (e == null) {
+                Toast.makeText(mContext, mContext.getString(R.string.storage_unmount_success,
+                        mDescription), Toast.LENGTH_SHORT).show();
+            } else {
+                Log.e(TAG, "Failed to unmount " + mVolumeId, e);
+                Toast.makeText(mContext, mContext.getString(R.string.storage_unmount_failure,
+                        mDescription), Toast.LENGTH_SHORT).show();
+            }
+        }
+    }
+
+    public static class FormatTask extends AsyncTask<Void, Void, Exception> {
+        private final Context mContext;
+        private final StorageManager mStorageManager;
+        private final String mVolumeId;
+        private final String mDescription;
+
+        public FormatTask(Context context, String volumeId) {
+            mContext = context.getApplicationContext();
+            mStorageManager = mContext.getSystemService(StorageManager.class);
+            mVolumeId = volumeId;
+            mDescription = mStorageManager.getBestVolumeDescription(mVolumeId);
+        }
+
+        @Override
+        protected Exception doInBackground(Void... params) {
+            try {
+                mStorageManager.format(mVolumeId);
+                mStorageManager.mount(mVolumeId);
+                return null;
+            } catch (Exception e) {
+                return e;
+            }
+        }
+
+        @Override
+        protected void onPostExecute(Exception e) {
+            if (e == null) {
+                Toast.makeText(mContext, mContext.getString(R.string.storage_format_success,
+                        mDescription), Toast.LENGTH_SHORT).show();
+            } else {
+                Log.e(TAG, "Failed to format " + mVolumeId, e);
+                Toast.makeText(mContext, mContext.getString(R.string.storage_format_failure,
+                        mDescription), Toast.LENGTH_SHORT).show();
+            }
+        }
+    }
+
+    /**
+     * Enable indexing of searchable data
+     */
+    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+        new BaseSearchIndexProvider() {
+            @Override
+            public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
+                final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
+
+                SearchIndexableRaw data = new SearchIndexableRaw(context);
+                data.title = context.getString(R.string.storage_settings);
+                data.screenTitle = context.getString(R.string.storage_settings);
+                result.add(data);
+
+                data = new SearchIndexableRaw(context);
+                data.title = context.getString(R.string.internal_storage);
+                data.screenTitle = context.getString(R.string.storage_settings);
+                result.add(data);
+
+                data = new SearchIndexableRaw(context);
+                final StorageManager storage = context.getSystemService(StorageManager.class);
+                final List<VolumeInfo> vols = storage.getVolumes();
+                for (VolumeInfo vol : vols) {
+                    if (isInteresting(vol)) {
+                        data.title = storage.getBestVolumeDescription(vol.id);
+                        data.screenTitle = context.getString(R.string.storage_settings);
+                        result.add(data);
+                    }
+                }
+
+                data = new SearchIndexableRaw(context);
+                data.title = context.getString(R.string.memory_size);
+                data.screenTitle = context.getString(R.string.storage_settings);
+                result.add(data);
+
+                data = new SearchIndexableRaw(context);
+                data.title = context.getString(R.string.memory_available);
+                data.screenTitle = context.getString(R.string.storage_settings);
+                result.add(data);
+
+                data = new SearchIndexableRaw(context);
+                data.title = context.getString(R.string.memory_apps_usage);
+                data.screenTitle = context.getString(R.string.storage_settings);
+                result.add(data);
+
+                data = new SearchIndexableRaw(context);
+                data.title = context.getString(R.string.memory_dcim_usage);
+                data.screenTitle = context.getString(R.string.storage_settings);
+                result.add(data);
+
+                data = new SearchIndexableRaw(context);
+                data.title = context.getString(R.string.memory_music_usage);
+                data.screenTitle = context.getString(R.string.storage_settings);
+                result.add(data);
+
+                data = new SearchIndexableRaw(context);
+                data.title = context.getString(R.string.memory_downloads_usage);
+                data.screenTitle = context.getString(R.string.storage_settings);
+                result.add(data);
+
+                data = new SearchIndexableRaw(context);
+                data.title = context.getString(R.string.memory_media_cache_usage);
+                data.screenTitle = context.getString(R.string.storage_settings);
+                result.add(data);
+
+                data = new SearchIndexableRaw(context);
+                data.title = context.getString(R.string.memory_media_misc_usage);
+                data.screenTitle = context.getString(R.string.storage_settings);
+                result.add(data);
+
+                return result;
+            }
+        };
+}
diff --git a/src/com/android/settings/deviceinfo/StorageVolumePreference.java b/src/com/android/settings/deviceinfo/StorageVolumePreference.java
new file mode 100644
index 0000000..fbe34f6
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/StorageVolumePreference.java
@@ -0,0 +1,89 @@
+/*
+ * 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.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.TextView;
+
+import com.android.settings.R;
+import com.android.settings.deviceinfo.StorageSettings.UnmountTask;
+
+import java.io.File;
+
+/**
+ * Preference line representing a single {@link VolumeInfo}, possibly including
+ * quick actions like unmounting.
+ */
+public class StorageVolumePreference extends Preference {
+    private final StorageManager mStorageManager;
+    private final VolumeInfo mVolume;
+
+    public StorageVolumePreference(Context context, VolumeInfo volume) {
+        super(context);
+
+        mStorageManager = context.getSystemService(StorageManager.class);
+        mVolume = volume;
+
+        setKey(volume.id);
+        setTitle(mStorageManager.getBestVolumeDescription(volume.id));
+
+        switch (volume.state) {
+            case VolumeInfo.STATE_MOUNTED:
+                // TODO: move statfs() to background thread
+                final File path = new File(volume.path);
+                final String free = Formatter.formatFileSize(context, path.getFreeSpace());
+                final String total = Formatter.formatFileSize(context, path.getTotalSpace());
+                setSummary(context.getString(R.string.storage_volume_summary, free, total));
+                break;
+        }
+
+        // TODO: better icons
+        if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(volume.id)) {
+            setIcon(context.getDrawable(R.drawable.ic_settings_storage));
+        } else {
+            setIcon(context.getDrawable(R.drawable.ic_sim_sd));
+        }
+
+        if (volume.type == VolumeInfo.TYPE_PUBLIC && volume.state == VolumeInfo.STATE_MOUNTED) {
+            setWidgetLayoutResource(R.layout.preference_storage_action);
+        }
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        final TextView unmount = (TextView) view.findViewById(R.id.unmount);
+        if (unmount != null) {
+            unmount.setText("\u23CF");
+            unmount.setOnClickListener(mUnmountListener);
+        }
+
+        super.onBindView(view);
+    }
+
+    private final View.OnClickListener mUnmountListener = new OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            new UnmountTask(getContext(), mVolume.id).execute();
+        }
+    };
+}
diff --git a/src/com/android/settings/deviceinfo/StorageVolumePreferenceCategory.java b/src/com/android/settings/deviceinfo/StorageVolumePreferenceCategory.java
deleted file mode 100644
index a98f8d9..0000000
--- a/src/com/android/settings/deviceinfo/StorageVolumePreferenceCategory.java
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (C) 2011 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.app.ActivityManagerNative;
-import android.app.ActivityThread;
-import android.app.DownloadManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.IPackageManager;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.hardware.usb.UsbManager;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.UserManager;
-import android.os.storage.StorageManager;
-import android.os.storage.StorageVolume;
-import android.preference.Preference;
-import android.preference.PreferenceCategory;
-import android.provider.MediaStore;
-import android.text.format.Formatter;
-
-import com.android.settings.R;
-import com.android.settings.Settings;
-import com.android.settings.deviceinfo.StorageMeasurement.MeasurementDetails;
-import com.android.settings.deviceinfo.StorageMeasurement.MeasurementReceiver;
-import com.google.android.collect.Lists;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-
-public class StorageVolumePreferenceCategory extends PreferenceCategory {
-    public static final String KEY_CACHE = "cache";
-
-    private static final int ORDER_USAGE_BAR = -2;
-    private static final int ORDER_STORAGE_LOW = -1;
-
-    /** Physical volume being measured, or {@code null} for internal. */
-    private final StorageVolume mVolume;
-    private final StorageMeasurement mMeasure;
-
-    private final Resources mResources;
-    private final StorageManager mStorageManager;
-    private final UserManager mUserManager;
-
-    private UsageBarPreference mUsageBarPreference;
-    private Preference mMountTogglePreference;
-    private Preference mFormatPreference;
-    private Preference mStorageLow;
-
-    private StorageItemPreference mItemTotal;
-    private StorageItemPreference mItemAvailable;
-    private StorageItemPreference mItemApps;
-    private StorageItemPreference mItemDcim;
-    private StorageItemPreference mItemMusic;
-    private StorageItemPreference mItemDownloads;
-    private StorageItemPreference mItemCache;
-    private StorageItemPreference mItemMisc;
-    private List<StorageItemPreference> mItemUsers = Lists.newArrayList();
-
-    private boolean mUsbConnected;
-    private String mUsbFunction;
-
-    private long mTotalSize;
-
-    private static final int MSG_UI_UPDATE_APPROXIMATE = 1;
-    private static final int MSG_UI_UPDATE_DETAILS = 2;
-
-    private Handler mUpdateHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_UI_UPDATE_APPROXIMATE: {
-                    final long[] size = (long[]) msg.obj;
-                    updateApproximate(size[0], size[1]);
-                    break;
-                }
-                case MSG_UI_UPDATE_DETAILS: {
-                    final MeasurementDetails details = (MeasurementDetails) msg.obj;
-                    updateDetails(details);
-                    break;
-                }
-            }
-        }
-    };
-
-    /**
-     * Build category to summarize internal storage, including any emulated
-     * {@link StorageVolume}.
-     */
-    public static StorageVolumePreferenceCategory buildForInternal(Context context) {
-        return new StorageVolumePreferenceCategory(context, null);
-    }
-
-    /**
-     * Build category to summarize specific physical {@link StorageVolume}.
-     */
-    public static StorageVolumePreferenceCategory buildForPhysical(
-            Context context, StorageVolume volume) {
-        return new StorageVolumePreferenceCategory(context, volume);
-    }
-
-    private StorageVolumePreferenceCategory(Context context, StorageVolume volume) {
-        super(context);
-
-        mVolume = volume;
-        mMeasure = StorageMeasurement.getInstance(context, volume);
-
-        mResources = context.getResources();
-        mStorageManager = StorageManager.from(context);
-        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-
-        setTitle(volume != null ? volume.getDescription(context)
-                : context.getText(R.string.internal_storage));
-    }
-
-    private StorageItemPreference buildItem(int titleRes, int colorRes) {
-        return new StorageItemPreference(getContext(), titleRes, colorRes);
-    }
-
-    public void init() {
-        final Context context = getContext();
-
-        removeAll();
-
-        final UserInfo currentUser;
-        try {
-            currentUser = ActivityManagerNative.getDefault().getCurrentUser();
-        } catch (RemoteException e) {
-            throw new RuntimeException("Failed to get current user");
-        }
-
-        final List<UserInfo> otherUsers = getUsersExcluding(currentUser);
-        final boolean showUsers = mVolume == null && otherUsers.size() > 0;
-
-        mUsageBarPreference = new UsageBarPreference(context);
-        mUsageBarPreference.setOrder(ORDER_USAGE_BAR);
-        addPreference(mUsageBarPreference);
-
-        mItemTotal = buildItem(R.string.memory_size, 0);
-        mItemAvailable = buildItem(R.string.memory_available, R.color.memory_avail);
-        addPreference(mItemTotal);
-        addPreference(mItemAvailable);
-
-        mItemApps = buildItem(R.string.memory_apps_usage, R.color.memory_apps_usage);
-        mItemDcim = buildItem(R.string.memory_dcim_usage, R.color.memory_dcim);
-        mItemMusic = buildItem(R.string.memory_music_usage, R.color.memory_music);
-        mItemDownloads = buildItem(R.string.memory_downloads_usage, R.color.memory_downloads);
-        mItemCache = buildItem(R.string.memory_media_cache_usage, R.color.memory_cache);
-        mItemMisc = buildItem(R.string.memory_media_misc_usage, R.color.memory_misc);
-
-        mItemCache.setKey(KEY_CACHE);
-
-        final boolean showDetails = mVolume == null || mVolume.isPrimary();
-        if (showDetails) {
-            if (showUsers) {
-                addPreference(new PreferenceHeader(context, currentUser.name));
-            }
-
-            addPreference(mItemApps);
-            addPreference(mItemDcim);
-            addPreference(mItemMusic);
-            addPreference(mItemDownloads);
-            addPreference(mItemCache);
-            addPreference(mItemMisc);
-
-            if (showUsers) {
-                addPreference(new PreferenceHeader(context, R.string.storage_other_users));
-
-                int count = 0;
-                for (UserInfo info : otherUsers) {
-                    final int colorRes = count++ % 2 == 0 ? R.color.memory_user_light
-                            : R.color.memory_user_dark;
-                    final StorageItemPreference userPref = new StorageItemPreference(
-                            getContext(), info.name, colorRes, info.id);
-                    mItemUsers.add(userPref);
-                    addPreference(userPref);
-                }
-            }
-        }
-
-        final boolean isRemovable = mVolume != null ? mVolume.isRemovable() : false;
-        // Always create the preference since many code rely on it existing
-        mMountTogglePreference = new Preference(context);
-        if (isRemovable) {
-            mMountTogglePreference.setTitle(R.string.sd_eject);
-            mMountTogglePreference.setSummary(R.string.sd_eject_summary);
-            addPreference(mMountTogglePreference);
-        }
-
-        final boolean allowFormat = mVolume != null;
-        if (allowFormat) {
-            mFormatPreference = new Preference(context);
-            mFormatPreference.setTitle(R.string.sd_format);
-            mFormatPreference.setSummary(R.string.sd_format_summary);
-            addPreference(mFormatPreference);
-        }
-
-        final IPackageManager pm = ActivityThread.getPackageManager();
-        try {
-            if (pm.isStorageLow()) {
-                mStorageLow = new Preference(context);
-                mStorageLow.setOrder(ORDER_STORAGE_LOW);
-                mStorageLow.setTitle(R.string.storage_low_title);
-                mStorageLow.setSummary(R.string.storage_low_summary);
-                addPreference(mStorageLow);
-            } else if (mStorageLow != null) {
-                removePreference(mStorageLow);
-                mStorageLow = null;
-            }
-        } catch (RemoteException e) {
-        }
-    }
-
-    public StorageVolume getStorageVolume() {
-        return mVolume;
-    }
-
-    private void updatePreferencesFromState() {
-        // Only update for physical volumes
-        if (mVolume == null) return;
-
-        mMountTogglePreference.setEnabled(true);
-
-        final String state = mStorageManager.getVolumeState(mVolume.getPath());
-
-        if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
-            mItemAvailable.setTitle(R.string.memory_available_read_only);
-        } else {
-            mItemAvailable.setTitle(R.string.memory_available);
-        }
-
-        if (Environment.MEDIA_MOUNTED.equals(state)
-                || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
-            mMountTogglePreference.setEnabled(true);
-            mMountTogglePreference.setTitle(mResources.getString(R.string.sd_eject));
-            mMountTogglePreference.setSummary(mResources.getString(R.string.sd_eject_summary));
-            addPreference(mUsageBarPreference);
-            addPreference(mItemTotal);
-            addPreference(mItemAvailable);
-        } else {
-            if (Environment.MEDIA_UNMOUNTED.equals(state) || Environment.MEDIA_NOFS.equals(state)
-                    || Environment.MEDIA_UNMOUNTABLE.equals(state)) {
-                mMountTogglePreference.setEnabled(true);
-                mMountTogglePreference.setTitle(mResources.getString(R.string.sd_mount));
-                mMountTogglePreference.setSummary(mResources.getString(R.string.sd_mount_summary));
-            } else {
-                mMountTogglePreference.setEnabled(false);
-                mMountTogglePreference.setTitle(mResources.getString(R.string.sd_mount));
-                mMountTogglePreference.setSummary(mResources.getString(R.string.sd_insert_summary));
-            }
-
-            removePreference(mUsageBarPreference);
-            removePreference(mItemTotal);
-            removePreference(mItemAvailable);
-        }
-
-        if (mUsbConnected && (UsbManager.USB_FUNCTION_MTP.equals(mUsbFunction) ||
-                UsbManager.USB_FUNCTION_PTP.equals(mUsbFunction))) {
-            mMountTogglePreference.setEnabled(false);
-            if (Environment.MEDIA_MOUNTED.equals(state)
-                    || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
-                mMountTogglePreference.setSummary(
-                        mResources.getString(R.string.mtp_ptp_mode_summary));
-            }
-
-            if (mFormatPreference != null) {
-                mFormatPreference.setEnabled(false);
-                mFormatPreference.setSummary(mResources.getString(R.string.mtp_ptp_mode_summary));
-            }
-        } else if (mFormatPreference != null) {
-            mFormatPreference.setEnabled(mMountTogglePreference.isEnabled());
-            mFormatPreference.setSummary(mResources.getString(R.string.sd_format_summary));
-        }
-    }
-
-    public void updateApproximate(long totalSize, long availSize) {
-        mItemTotal.setSummary(formatSize(totalSize));
-        mItemAvailable.setSummary(formatSize(availSize));
-
-        mTotalSize = totalSize;
-
-        final long usedSize = totalSize - availSize;
-
-        mUsageBarPreference.clear();
-        mUsageBarPreference.addEntry(0, usedSize / (float) totalSize, android.graphics.Color.GRAY);
-        mUsageBarPreference.commit();
-
-        updatePreferencesFromState();
-    }
-
-    private static long totalValues(HashMap<String, Long> map, String... keys) {
-        long total = 0;
-        for (String key : keys) {
-            if (map.containsKey(key)) {
-                total += map.get(key);
-            }
-        }
-        return total;
-    }
-
-    public void updateDetails(MeasurementDetails details) {
-        final boolean showDetails = mVolume == null || mVolume.isPrimary();
-        if (!showDetails) return;
-
-        // Count caches as available space, since system manages them
-        mItemTotal.setSummary(formatSize(details.totalSize));
-        mItemAvailable.setSummary(formatSize(details.availSize));
-
-        mUsageBarPreference.clear();
-
-        updatePreference(mItemApps, details.appsSize);
-
-        final long dcimSize = totalValues(details.mediaSize, Environment.DIRECTORY_DCIM,
-                Environment.DIRECTORY_MOVIES, Environment.DIRECTORY_PICTURES);
-        updatePreference(mItemDcim, dcimSize);
-
-        final long musicSize = totalValues(details.mediaSize, Environment.DIRECTORY_MUSIC,
-                Environment.DIRECTORY_ALARMS, Environment.DIRECTORY_NOTIFICATIONS,
-                Environment.DIRECTORY_RINGTONES, Environment.DIRECTORY_PODCASTS);
-        updatePreference(mItemMusic, musicSize);
-
-        final long downloadsSize = totalValues(details.mediaSize, Environment.DIRECTORY_DOWNLOADS);
-        updatePreference(mItemDownloads, downloadsSize);
-
-        updatePreference(mItemCache, details.cacheSize);
-        updatePreference(mItemMisc, details.miscSize);
-
-        for (StorageItemPreference userPref : mItemUsers) {
-            final long userSize = details.usersSize.get(userPref.userHandle);
-            updatePreference(userPref, userSize);
-        }
-
-        mUsageBarPreference.commit();
-    }
-
-    private void updatePreference(StorageItemPreference pref, long size) {
-        if (size > 0) {
-            pref.setSummary(formatSize(size));
-            final int order = pref.getOrder();
-            mUsageBarPreference.addEntry(order, size / (float) mTotalSize, pref.color);
-        } else {
-            removePreference(pref);
-        }
-    }
-
-    private void measure() {
-        mMeasure.invalidate();
-        mMeasure.measure();
-    }
-
-    public void onResume() {
-        mMeasure.setReceiver(mReceiver);
-        measure();
-    }
-
-    public void onStorageStateChanged() {
-        init();
-        measure();
-    }
-
-    public void onUsbStateChanged(boolean isUsbConnected, String usbFunction) {
-        mUsbConnected = isUsbConnected;
-        mUsbFunction = usbFunction;
-        measure();
-    }
-
-    public void onMediaScannerFinished() {
-        measure();
-    }
-
-    public void onCacheCleared() {
-        measure();
-    }
-
-    public void onPause() {
-        mMeasure.cleanUp();
-    }
-
-    private String formatSize(long size) {
-        return Formatter.formatFileSize(getContext(), size);
-    }
-
-    private MeasurementReceiver mReceiver = new MeasurementReceiver() {
-        @Override
-        public void updateApproximate(StorageMeasurement meas, long totalSize, long availSize) {
-            mUpdateHandler.obtainMessage(MSG_UI_UPDATE_APPROXIMATE, new long[] {
-                    totalSize, availSize }).sendToTarget();
-        }
-
-        @Override
-        public void updateDetails(StorageMeasurement meas, MeasurementDetails details) {
-            mUpdateHandler.obtainMessage(MSG_UI_UPDATE_DETAILS, details).sendToTarget();
-        }
-    };
-
-    public boolean mountToggleClicked(Preference preference) {
-        return preference == mMountTogglePreference;
-    }
-
-    public Intent intentForClick(Preference pref) {
-        Intent intent = null;
-
-        // TODO The current "delete" story is not fully handled by the respective applications.
-        // When it is done, make sure the intent types below are correct.
-        // If that cannot be done, remove these intents.
-        final String key = pref.getKey();
-        if (pref == mFormatPreference) {
-            intent = new Intent(Intent.ACTION_VIEW);
-            intent.setClass(getContext(), com.android.settings.MediaFormat.class);
-            intent.putExtra(StorageVolume.EXTRA_STORAGE_VOLUME, mVolume);
-        } else if (pref == mItemApps) {
-            intent = new Intent(Intent.ACTION_MANAGE_PACKAGE_STORAGE);
-            intent.setClass(getContext(), Settings.ManageApplicationsActivity.class);
-        } else if (pref == mItemDownloads) {
-            intent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS).putExtra(
-                    DownloadManager.INTENT_EXTRAS_SORT_BY_SIZE, true);
-        } else if (pref == mItemMusic) {
-            intent = new Intent(Intent.ACTION_GET_CONTENT);
-            intent.setType("audio/mp3");
-        } else if (pref == mItemDcim) {
-            intent = new Intent(Intent.ACTION_VIEW);
-            intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
-            // TODO Create a Videos category, MediaStore.Video.Media.EXTERNAL_CONTENT_URI
-            intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
-        } else if (pref == mItemMisc) {
-            Context context = getContext().getApplicationContext();
-            intent = new Intent(context, MiscFilesHandler.class);
-            intent.putExtra(StorageVolume.EXTRA_STORAGE_VOLUME, mVolume);
-        }
-
-        return intent;
-    }
-
-    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;
-        }
-    }
-
-    /**
-     * Return list of other users, excluding the current user.
-     */
-    private List<UserInfo> getUsersExcluding(UserInfo excluding) {
-        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;
-    }
-}
diff --git a/src/com/android/settings/search/Ranking.java b/src/com/android/settings/search/Ranking.java
index f37e1fc..2143d0d 100644
--- a/src/com/android/settings/search/Ranking.java
+++ b/src/com/android/settings/search/Ranking.java
@@ -32,7 +32,7 @@
 import com.android.settings.accessibility.AccessibilitySettings;
 import com.android.settings.applications.AdvancedAppSettings;
 import com.android.settings.bluetooth.BluetoothSettings;
-import com.android.settings.deviceinfo.Memory;
+import com.android.settings.deviceinfo.StorageSettings;
 import com.android.settings.deviceinfo.UsbSettings;
 import com.android.settings.fuelgauge.BatterySaverSettings;
 import com.android.settings.fuelgauge.PowerUsageSummary;
@@ -129,7 +129,7 @@
         sRankMap.put(ZenModeAutomationSettings.class.getName(), RANK_NOTIFICATIONS);
 
         // Storage
-        sRankMap.put(Memory.class.getName(), RANK_STORAGE);
+        sRankMap.put(StorageSettings.class.getName(), RANK_STORAGE);
         sRankMap.put(UsbSettings.class.getName(), RANK_STORAGE);
 
         // Battery
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index dae8860..b7bb062 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -34,7 +34,7 @@
 import com.android.settings.accessibility.AccessibilitySettings;
 import com.android.settings.applications.AdvancedAppSettings;
 import com.android.settings.bluetooth.BluetoothSettings;
-import com.android.settings.deviceinfo.Memory;
+import com.android.settings.deviceinfo.StorageSettings;
 import com.android.settings.deviceinfo.UsbSettings;
 import com.android.settings.fuelgauge.BatterySaverSettings;
 import com.android.settings.fuelgauge.PowerUsageSummary;
@@ -170,11 +170,11 @@
                         ZenModePrioritySettings.class.getName(),
                         R.drawable.ic_settings_notifications));
 
-        sResMap.put(Memory.class.getName(),
+        sResMap.put(StorageSettings.class.getName(),
                 new SearchIndexableResource(
-                        Ranking.getRankForClassName(Memory.class.getName()),
+                        Ranking.getRankForClassName(StorageSettings.class.getName()),
                         NO_DATA_RES_ID,
-                        Memory.class.getName(),
+                        StorageSettings.class.getName(),
                         R.drawable.ic_settings_storage));
 
         sResMap.put(UsbSettings.class.getName(),
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index cc8481d..1503c63 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -88,6 +88,9 @@
     public static final int WIFI_EAP_METHOD_TLS  = 1;
     public static final int WIFI_EAP_METHOD_TTLS = 2;
     public static final int WIFI_EAP_METHOD_PWD  = 3;
+    public static final int WIFI_EAP_METHOD_SIM  = 4;
+    public static final int WIFI_EAP_METHOD_AKA  = 5;
+    public static final int WIFI_EAP_METHOD_AKA_PRIME  = 6;
 
     /* These values come from "wifi_peap_phase2_entries" resource array */
     public static final int WIFI_PEAP_PHASE2_NONE 	    = 0;
@@ -734,9 +737,23 @@
                 mView.findViewById(R.id.l_anonymous).setVisibility(View.VISIBLE);
                 setUserCertInvisible();
                 break;
+            case WIFI_EAP_METHOD_SIM:
+            case WIFI_EAP_METHOD_AKA:
+            case WIFI_EAP_METHOD_AKA_PRIME:
+                setPhase2Invisible();
+                setAnonymousIdentInvisible();
+                setUserCertInvisible();
+                setPasswordInvisible();
+                setIdentityInvisible();
+                break;
         }
     }
 
+    private void setIdentityInvisible() {
+        mView.findViewById(R.id.l_identity).setVisibility(View.GONE);
+        mPhase2Spinner.setSelection(Phase2.NONE);
+    }
+
     private void setPhase2Invisible() {
         mView.findViewById(R.id.l_phase2).setVisibility(View.GONE);
         mPhase2Spinner.setSelection(Phase2.NONE);
