Home | History | Annotate | Download | only in deviceinfo
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings.deviceinfo;
     18 
     19 import android.app.Activity;
     20 import android.app.AlertDialog;
     21 import android.app.Dialog;
     22 import android.app.DialogFragment;
     23 import android.app.Fragment;
     24 import android.content.Context;
     25 import android.content.DialogInterface;
     26 import android.content.Intent;
     27 import android.graphics.Color;
     28 import android.graphics.drawable.Drawable;
     29 import android.os.AsyncTask;
     30 import android.os.Bundle;
     31 import android.os.UserHandle;
     32 import android.os.UserManager;
     33 import android.os.storage.DiskInfo;
     34 import android.os.storage.StorageEventListener;
     35 import android.os.storage.StorageManager;
     36 import android.os.storage.VolumeInfo;
     37 import android.os.storage.VolumeRecord;
     38 import android.support.v7.preference.Preference;
     39 import android.support.v7.preference.PreferenceCategory;
     40 import android.text.TextUtils;
     41 import android.text.format.Formatter;
     42 import android.text.format.Formatter.BytesResult;
     43 import android.util.Log;
     44 import android.widget.Toast;
     45 
     46 import com.android.internal.logging.MetricsProto.MetricsEvent;
     47 import com.android.settings.R;
     48 import com.android.settings.SettingsPreferenceFragment;
     49 import com.android.settings.Utils;
     50 import com.android.settings.dashboard.SummaryLoader;
     51 import com.android.settings.search.BaseSearchIndexProvider;
     52 import com.android.settings.search.Indexable;
     53 import com.android.settings.search.SearchIndexableRaw;
     54 import com.android.settingslib.RestrictedLockUtils;
     55 import com.android.settingslib.drawer.SettingsDrawerActivity;
     56 
     57 import java.io.File;
     58 import java.util.ArrayList;
     59 import java.util.Collections;
     60 import java.util.List;
     61 
     62 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
     63 
     64 /**
     65  * Panel showing both internal storage (both built-in storage and private
     66  * volumes) and removable storage (public volumes).
     67  */
     68 public class StorageSettings extends SettingsPreferenceFragment implements Indexable {
     69     static final String TAG = "StorageSettings";
     70 
     71     private static final String TAG_VOLUME_UNMOUNTED = "volume_unmounted";
     72     private static final String TAG_DISK_INIT = "disk_init";
     73 
     74     static final int COLOR_PUBLIC = Color.parseColor("#ff9e9e9e");
     75     static final int COLOR_WARNING = Color.parseColor("#fff4511e");
     76 
     77     static final int[] COLOR_PRIVATE = new int[] {
     78             Color.parseColor("#ff26a69a"),
     79             Color.parseColor("#ffab47bc"),
     80             Color.parseColor("#fff2a600"),
     81             Color.parseColor("#ffec407a"),
     82             Color.parseColor("#ffc0ca33"),
     83     };
     84 
     85     private StorageManager mStorageManager;
     86 
     87     private PreferenceCategory mInternalCategory;
     88     private PreferenceCategory mExternalCategory;
     89 
     90     private StorageSummaryPreference mInternalSummary;
     91     private static long sTotalInternalStorage;
     92 
     93     @Override
     94     protected int getMetricsCategory() {
     95         return MetricsEvent.DEVICEINFO_STORAGE;
     96     }
     97 
     98     @Override
     99     protected int getHelpResource() {
    100         return R.string.help_uri_storage;
    101     }
    102 
    103     @Override
    104     public void onCreate(Bundle icicle) {
    105         super.onCreate(icicle);
    106 
    107         final Context context = getActivity();
    108 
    109         mStorageManager = context.getSystemService(StorageManager.class);
    110         mStorageManager.registerListener(mStorageListener);
    111 
    112         if (sTotalInternalStorage <= 0) {
    113             sTotalInternalStorage = mStorageManager.getPrimaryStorageSize();
    114         }
    115 
    116         addPreferencesFromResource(R.xml.device_info_storage);
    117 
    118         mInternalCategory = (PreferenceCategory) findPreference("storage_internal");
    119         mExternalCategory = (PreferenceCategory) findPreference("storage_external");
    120 
    121         mInternalSummary = new StorageSummaryPreference(getPrefContext());
    122 
    123         setHasOptionsMenu(true);
    124     }
    125 
    126     private final StorageEventListener mStorageListener = new StorageEventListener() {
    127         @Override
    128         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
    129             if (isInteresting(vol)) {
    130                 refresh();
    131             }
    132         }
    133 
    134         @Override
    135         public void onDiskDestroyed(DiskInfo disk) {
    136             refresh();
    137         }
    138     };
    139 
    140     private static boolean isInteresting(VolumeInfo vol) {
    141         switch(vol.getType()) {
    142             case VolumeInfo.TYPE_PRIVATE:
    143             case VolumeInfo.TYPE_PUBLIC:
    144                 return true;
    145             default:
    146                 return false;
    147         }
    148     }
    149 
    150     private void refresh() {
    151         final Context context = getPrefContext();
    152 
    153         getPreferenceScreen().removeAll();
    154         mInternalCategory.removeAll();
    155         mExternalCategory.removeAll();
    156 
    157         mInternalCategory.addPreference(mInternalSummary);
    158 
    159         int privateCount = 0;
    160         long privateUsedBytes = 0;
    161         long privateTotalBytes = 0;
    162 
    163         final List<VolumeInfo> volumes = mStorageManager.getVolumes();
    164         Collections.sort(volumes, VolumeInfo.getDescriptionComparator());
    165 
    166         for (VolumeInfo vol : volumes) {
    167             if (vol.getType() == VolumeInfo.TYPE_PRIVATE) {
    168                 final int color = COLOR_PRIVATE[privateCount++ % COLOR_PRIVATE.length];
    169                 mInternalCategory.addPreference(
    170                         new StorageVolumePreference(context, vol, color, sTotalInternalStorage));
    171                 if (vol.isMountedReadable()) {
    172                     final File path = vol.getPath();
    173                     privateUsedBytes += path.getTotalSpace() - path.getFreeSpace();
    174                     if (sTotalInternalStorage > 0) {
    175                         privateTotalBytes = sTotalInternalStorage;
    176                     } else {
    177                         privateTotalBytes += path.getTotalSpace();
    178                     }
    179                 }
    180             } else if (vol.getType() == VolumeInfo.TYPE_PUBLIC) {
    181                 mExternalCategory.addPreference(
    182                         new StorageVolumePreference(context, vol, COLOR_PUBLIC, 0));
    183             }
    184         }
    185 
    186         // Show missing private volumes
    187         final List<VolumeRecord> recs = mStorageManager.getVolumeRecords();
    188         for (VolumeRecord rec : recs) {
    189             if (rec.getType() == VolumeInfo.TYPE_PRIVATE
    190                     && mStorageManager.findVolumeByUuid(rec.getFsUuid()) == null) {
    191                 // TODO: add actual storage type to record
    192                 final Drawable icon = context.getDrawable(R.drawable.ic_sim_sd);
    193                 icon.mutate();
    194                 icon.setTint(COLOR_PUBLIC);
    195 
    196                 final Preference pref = new Preference(context);
    197                 pref.setKey(rec.getFsUuid());
    198                 pref.setTitle(rec.getNickname());
    199                 pref.setSummary(com.android.internal.R.string.ext_media_status_missing);
    200                 pref.setIcon(icon);
    201                 mInternalCategory.addPreference(pref);
    202             }
    203         }
    204 
    205         // Show unsupported disks to give a chance to init
    206         final List<DiskInfo> disks = mStorageManager.getDisks();
    207         for (DiskInfo disk : disks) {
    208             if (disk.volumeCount == 0 && disk.size > 0) {
    209                 final Preference pref = new Preference(context);
    210                 pref.setKey(disk.getId());
    211                 pref.setTitle(disk.getDescription());
    212                 pref.setSummary(com.android.internal.R.string.ext_media_status_unsupported);
    213                 pref.setIcon(R.drawable.ic_sim_sd);
    214                 mExternalCategory.addPreference(pref);
    215             }
    216         }
    217 
    218         final BytesResult result = Formatter.formatBytes(getResources(), privateUsedBytes, 0);
    219         mInternalSummary.setTitle(TextUtils.expandTemplate(getText(R.string.storage_size_large),
    220                 result.value, result.units));
    221         mInternalSummary.setSummary(getString(R.string.storage_volume_used_total,
    222                 Formatter.formatFileSize(context, privateTotalBytes)));
    223         if (mInternalCategory.getPreferenceCount() > 0) {
    224             getPreferenceScreen().addPreference(mInternalCategory);
    225         }
    226         if (mExternalCategory.getPreferenceCount() > 0) {
    227             getPreferenceScreen().addPreference(mExternalCategory);
    228         }
    229 
    230         if (mInternalCategory.getPreferenceCount() == 2
    231                 && mExternalCategory.getPreferenceCount() == 0) {
    232             // Only showing primary internal storage, so just shortcut
    233             final Bundle args = new Bundle();
    234             args.putString(VolumeInfo.EXTRA_VOLUME_ID, VolumeInfo.ID_PRIVATE_INTERNAL);
    235             PrivateVolumeSettings.setVolumeSize(args, sTotalInternalStorage);
    236             Intent intent = Utils.onBuildStartFragmentIntent(getActivity(),
    237                     PrivateVolumeSettings.class.getName(), args, null, R.string.apps_storage, null,
    238                     false);
    239             intent.putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true);
    240             getActivity().startActivity(intent);
    241             finish();
    242         }
    243     }
    244 
    245     @Override
    246     public void onResume() {
    247         super.onResume();
    248         mStorageManager.registerListener(mStorageListener);
    249         refresh();
    250     }
    251 
    252     @Override
    253     public void onPause() {
    254         super.onPause();
    255         mStorageManager.unregisterListener(mStorageListener);
    256     }
    257 
    258     @Override
    259     public boolean onPreferenceTreeClick(Preference pref) {
    260         final String key = pref.getKey();
    261         if (pref instanceof StorageVolumePreference) {
    262             // Picked a normal volume
    263             final VolumeInfo vol = mStorageManager.findVolumeById(key);
    264 
    265             if (vol == null) {
    266                 return false;
    267             }
    268 
    269             if (vol.getState() == VolumeInfo.STATE_UNMOUNTED) {
    270                 VolumeUnmountedFragment.show(this, vol.getId());
    271                 return true;
    272             } else if (vol.getState() == VolumeInfo.STATE_UNMOUNTABLE) {
    273                 DiskInitFragment.show(this, R.string.storage_dialog_unmountable, vol.getDiskId());
    274                 return true;
    275             }
    276 
    277             if (vol.getType() == VolumeInfo.TYPE_PRIVATE) {
    278                 final Bundle args = new Bundle();
    279                 args.putString(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
    280                 PrivateVolumeSettings.setVolumeSize(args, sTotalInternalStorage);
    281                 startFragment(this, PrivateVolumeSettings.class.getCanonicalName(),
    282                         -1, 0, args);
    283                 return true;
    284 
    285             } else if (vol.getType() == VolumeInfo.TYPE_PUBLIC) {
    286                 if (vol.isMountedReadable()) {
    287                     startActivity(vol.buildBrowseIntent());
    288                     return true;
    289                 } else {
    290                     final Bundle args = new Bundle();
    291                     args.putString(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
    292                     startFragment(this, PublicVolumeSettings.class.getCanonicalName(),
    293                             -1, 0, args);
    294                     return true;
    295                 }
    296             }
    297 
    298         } else if (key.startsWith("disk:")) {
    299             // Picked an unsupported disk
    300             DiskInitFragment.show(this, R.string.storage_dialog_unsupported, key);
    301             return true;
    302 
    303         } else {
    304             // Picked a missing private volume
    305             final Bundle args = new Bundle();
    306             args.putString(VolumeRecord.EXTRA_FS_UUID, key);
    307             startFragment(this, PrivateVolumeForget.class.getCanonicalName(),
    308                     R.string.storage_menu_forget, 0, args);
    309             return true;
    310         }
    311 
    312         return false;
    313     }
    314 
    315     public static class MountTask extends AsyncTask<Void, Void, Exception> {
    316         private final Context mContext;
    317         private final StorageManager mStorageManager;
    318         private final String mVolumeId;
    319         private final String mDescription;
    320 
    321         public MountTask(Context context, VolumeInfo volume) {
    322             mContext = context.getApplicationContext();
    323             mStorageManager = mContext.getSystemService(StorageManager.class);
    324             mVolumeId = volume.getId();
    325             mDescription = mStorageManager.getBestVolumeDescription(volume);
    326         }
    327 
    328         @Override
    329         protected Exception doInBackground(Void... params) {
    330             try {
    331                 mStorageManager.mount(mVolumeId);
    332                 return null;
    333             } catch (Exception e) {
    334                 return e;
    335             }
    336         }
    337 
    338         @Override
    339         protected void onPostExecute(Exception e) {
    340             if (e == null) {
    341                 Toast.makeText(mContext, mContext.getString(R.string.storage_mount_success,
    342                         mDescription), Toast.LENGTH_SHORT).show();
    343             } else {
    344                 Log.e(TAG, "Failed to mount " + mVolumeId, e);
    345                 Toast.makeText(mContext, mContext.getString(R.string.storage_mount_failure,
    346                         mDescription), Toast.LENGTH_SHORT).show();
    347             }
    348         }
    349     }
    350 
    351     public static class UnmountTask extends AsyncTask<Void, Void, Exception> {
    352         private final Context mContext;
    353         private final StorageManager mStorageManager;
    354         private final String mVolumeId;
    355         private final String mDescription;
    356 
    357         public UnmountTask(Context context, VolumeInfo volume) {
    358             mContext = context.getApplicationContext();
    359             mStorageManager = mContext.getSystemService(StorageManager.class);
    360             mVolumeId = volume.getId();
    361             mDescription = mStorageManager.getBestVolumeDescription(volume);
    362         }
    363 
    364         @Override
    365         protected Exception doInBackground(Void... params) {
    366             try {
    367                 mStorageManager.unmount(mVolumeId);
    368                 return null;
    369             } catch (Exception e) {
    370                 return e;
    371             }
    372         }
    373 
    374         @Override
    375         protected void onPostExecute(Exception e) {
    376             if (e == null) {
    377                 Toast.makeText(mContext, mContext.getString(R.string.storage_unmount_success,
    378                         mDescription), Toast.LENGTH_SHORT).show();
    379             } else {
    380                 Log.e(TAG, "Failed to unmount " + mVolumeId, e);
    381                 Toast.makeText(mContext, mContext.getString(R.string.storage_unmount_failure,
    382                         mDescription), Toast.LENGTH_SHORT).show();
    383             }
    384         }
    385     }
    386 
    387     public static class VolumeUnmountedFragment extends DialogFragment {
    388         public static void show(Fragment parent, String volumeId) {
    389             final Bundle args = new Bundle();
    390             args.putString(VolumeInfo.EXTRA_VOLUME_ID, volumeId);
    391 
    392             final VolumeUnmountedFragment dialog = new VolumeUnmountedFragment();
    393             dialog.setArguments(args);
    394             dialog.setTargetFragment(parent, 0);
    395             dialog.show(parent.getFragmentManager(), TAG_VOLUME_UNMOUNTED);
    396         }
    397 
    398         @Override
    399         public Dialog onCreateDialog(Bundle savedInstanceState) {
    400             final Context context = getActivity();
    401             final StorageManager sm = context.getSystemService(StorageManager.class);
    402 
    403             final String volumeId = getArguments().getString(VolumeInfo.EXTRA_VOLUME_ID);
    404             final VolumeInfo vol = sm.findVolumeById(volumeId);
    405 
    406             final AlertDialog.Builder builder = new AlertDialog.Builder(context);
    407             builder.setMessage(TextUtils.expandTemplate(
    408                     getText(R.string.storage_dialog_unmounted), vol.getDisk().getDescription()));
    409 
    410             builder.setPositiveButton(R.string.storage_menu_mount,
    411                     new DialogInterface.OnClickListener() {
    412                 @Override
    413                 public void onClick(DialogInterface dialog, int which) {
    414                     EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
    415                             getActivity(), UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
    416                             UserHandle.myUserId());
    417                     boolean hasBaseUserRestriction = RestrictedLockUtils.hasBaseUserRestriction(
    418                             getActivity(), UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
    419                             UserHandle.myUserId());
    420                     if (admin != null && !hasBaseUserRestriction) {
    421                         RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getActivity(), admin);
    422                         return;
    423                     }
    424                     new MountTask(context, vol).execute();
    425                 }
    426             });
    427             builder.setNegativeButton(R.string.cancel, null);
    428 
    429             return builder.create();
    430         }
    431     }
    432 
    433     public static class DiskInitFragment extends DialogFragment {
    434         public static void show(Fragment parent, int resId, String diskId) {
    435             final Bundle args = new Bundle();
    436             args.putInt(Intent.EXTRA_TEXT, resId);
    437             args.putString(DiskInfo.EXTRA_DISK_ID, diskId);
    438 
    439             final DiskInitFragment dialog = new DiskInitFragment();
    440             dialog.setArguments(args);
    441             dialog.setTargetFragment(parent, 0);
    442             dialog.show(parent.getFragmentManager(), TAG_DISK_INIT);
    443         }
    444 
    445         @Override
    446         public Dialog onCreateDialog(Bundle savedInstanceState) {
    447             final Context context = getActivity();
    448             final StorageManager sm = context.getSystemService(StorageManager.class);
    449 
    450             final int resId = getArguments().getInt(Intent.EXTRA_TEXT);
    451             final String diskId = getArguments().getString(DiskInfo.EXTRA_DISK_ID);
    452             final DiskInfo disk = sm.findDiskById(diskId);
    453 
    454             final AlertDialog.Builder builder = new AlertDialog.Builder(context);
    455             builder.setMessage(TextUtils.expandTemplate(getText(resId), disk.getDescription()));
    456 
    457             builder.setPositiveButton(R.string.storage_menu_set_up,
    458                     new DialogInterface.OnClickListener() {
    459                 @Override
    460                 public void onClick(DialogInterface dialog, int which) {
    461                     final Intent intent = new Intent(context, StorageWizardInit.class);
    462                     intent.putExtra(DiskInfo.EXTRA_DISK_ID, diskId);
    463                     startActivity(intent);
    464                 }
    465             });
    466             builder.setNegativeButton(R.string.cancel, null);
    467 
    468             return builder.create();
    469         }
    470     }
    471 
    472     private static class SummaryProvider implements SummaryLoader.SummaryProvider {
    473         private final Context mContext;
    474         private final SummaryLoader mLoader;
    475 
    476         private SummaryProvider(Context context, SummaryLoader loader) {
    477             mContext = context;
    478             mLoader = loader;
    479         }
    480 
    481         @Override
    482         public void setListening(boolean listening) {
    483             if (listening) {
    484                 updateSummary();
    485             }
    486         }
    487 
    488         private void updateSummary() {
    489             // TODO: Register listener.
    490             final StorageManager storageManager = mContext.getSystemService(StorageManager.class);
    491             if (sTotalInternalStorage <= 0) {
    492                 sTotalInternalStorage = storageManager.getPrimaryStorageSize();
    493             }
    494             final List<VolumeInfo> volumes = storageManager.getVolumes();
    495             long privateFreeBytes = 0;
    496             long privateTotalBytes = 0;
    497             for (VolumeInfo info : volumes) {
    498                 if (info.getType() != VolumeInfo.TYPE_PUBLIC
    499                         && info.getType() != VolumeInfo.TYPE_PRIVATE) {
    500                     continue;
    501                 }
    502                 final File path = info.getPath();
    503                 if (path == null) {
    504                     continue;
    505                 }
    506                 if (info.getType() == VolumeInfo.TYPE_PRIVATE && sTotalInternalStorage > 0) {
    507                     privateTotalBytes = sTotalInternalStorage;
    508                 } else {
    509                     privateTotalBytes += path.getTotalSpace();
    510                 }
    511                 privateFreeBytes += path.getFreeSpace();
    512             }
    513             long privateUsedBytes = privateTotalBytes - privateFreeBytes;
    514             mLoader.setSummary(this, mContext.getString(R.string.storage_summary,
    515                     Formatter.formatFileSize(mContext, privateUsedBytes),
    516                     Formatter.formatFileSize(mContext, privateTotalBytes)));
    517         }
    518     }
    519 
    520     public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
    521             = new SummaryLoader.SummaryProviderFactory() {
    522         @Override
    523         public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
    524                                                                    SummaryLoader summaryLoader) {
    525             return new SummaryProvider(activity, summaryLoader);
    526         }
    527     };
    528 
    529     /**
    530      * Enable indexing of searchable data
    531      */
    532     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
    533         new BaseSearchIndexProvider() {
    534             @Override
    535             public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
    536                 final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
    537 
    538                 SearchIndexableRaw data = new SearchIndexableRaw(context);
    539                 data.title = context.getString(R.string.storage_settings);
    540                 data.screenTitle = context.getString(R.string.storage_settings);
    541                 result.add(data);
    542 
    543                 data = new SearchIndexableRaw(context);
    544                 data.title = context.getString(R.string.internal_storage);
    545                 data.screenTitle = context.getString(R.string.storage_settings);
    546                 result.add(data);
    547 
    548                 data = new SearchIndexableRaw(context);
    549                 final StorageManager storage = context.getSystemService(StorageManager.class);
    550                 final List<VolumeInfo> vols = storage.getVolumes();
    551                 for (VolumeInfo vol : vols) {
    552                     if (isInteresting(vol)) {
    553                         data.title = storage.getBestVolumeDescription(vol);
    554                         data.screenTitle = context.getString(R.string.storage_settings);
    555                         result.add(data);
    556                     }
    557                 }
    558 
    559                 data = new SearchIndexableRaw(context);
    560                 data.title = context.getString(R.string.memory_size);
    561                 data.screenTitle = context.getString(R.string.storage_settings);
    562                 result.add(data);
    563 
    564                 data = new SearchIndexableRaw(context);
    565                 data.title = context.getString(R.string.memory_available);
    566                 data.screenTitle = context.getString(R.string.storage_settings);
    567                 result.add(data);
    568 
    569                 data = new SearchIndexableRaw(context);
    570                 data.title = context.getString(R.string.memory_apps_usage);
    571                 data.screenTitle = context.getString(R.string.storage_settings);
    572                 result.add(data);
    573 
    574                 data = new SearchIndexableRaw(context);
    575                 data.title = context.getString(R.string.memory_dcim_usage);
    576                 data.screenTitle = context.getString(R.string.storage_settings);
    577                 result.add(data);
    578 
    579                 data = new SearchIndexableRaw(context);
    580                 data.title = context.getString(R.string.memory_music_usage);
    581                 data.screenTitle = context.getString(R.string.storage_settings);
    582                 result.add(data);
    583 
    584                 data = new SearchIndexableRaw(context);
    585                 data.title = context.getString(R.string.memory_downloads_usage);
    586                 data.screenTitle = context.getString(R.string.storage_settings);
    587                 result.add(data);
    588 
    589                 data = new SearchIndexableRaw(context);
    590                 data.title = context.getString(R.string.memory_media_cache_usage);
    591                 data.screenTitle = context.getString(R.string.storage_settings);
    592                 result.add(data);
    593 
    594                 data = new SearchIndexableRaw(context);
    595                 data.title = context.getString(R.string.memory_media_misc_usage);
    596                 data.screenTitle = context.getString(R.string.storage_settings);
    597                 result.add(data);
    598 
    599                 return result;
    600             }
    601         };
    602 }
    603