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.ActivityManager;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.net.Uri;
     23 import android.os.Bundle;
     24 import android.os.UserManager;
     25 import android.os.storage.DiskInfo;
     26 import android.os.storage.StorageEventListener;
     27 import android.os.storage.StorageManager;
     28 import android.os.storage.VolumeInfo;
     29 import android.os.storage.VolumeRecord;
     30 import android.preference.Preference;
     31 import android.preference.PreferenceScreen;
     32 import android.provider.DocumentsContract;
     33 import android.text.TextUtils;
     34 import android.text.format.Formatter;
     35 import android.text.format.Formatter.BytesResult;
     36 
     37 import com.android.internal.logging.MetricsLogger;
     38 import com.android.internal.util.Preconditions;
     39 import com.android.settings.R;
     40 import com.android.settings.SettingsPreferenceFragment;
     41 import com.android.settings.deviceinfo.StorageSettings.MountTask;
     42 import com.android.settings.deviceinfo.StorageSettings.UnmountTask;
     43 
     44 import java.io.File;
     45 import java.util.Objects;
     46 
     47 /**
     48  * Panel showing summary and actions for a {@link VolumeInfo#TYPE_PUBLIC}
     49  * storage volume.
     50  */
     51 public class PublicVolumeSettings extends SettingsPreferenceFragment {
     52     // TODO: disable unmount when providing over MTP/PTP
     53 
     54     private StorageManager mStorageManager;
     55 
     56     private String mVolumeId;
     57     private VolumeInfo mVolume;
     58     private DiskInfo mDisk;
     59 
     60     private StorageSummaryPreference mSummary;
     61 
     62     private Preference mMount;
     63     private Preference mUnmount;
     64     private Preference mFormatPublic;
     65     private Preference mFormatPrivate;
     66 
     67     private boolean mIsPermittedToAdopt;
     68 
     69     private boolean isVolumeValid() {
     70         return (mVolume != null) && (mVolume.getType() == VolumeInfo.TYPE_PUBLIC)
     71                 && mVolume.isMountedReadable();
     72     }
     73 
     74     @Override
     75     protected int getMetricsCategory() {
     76         return MetricsLogger.DEVICEINFO_STORAGE;
     77     }
     78 
     79     @Override
     80     public void onCreate(Bundle icicle) {
     81         super.onCreate(icicle);
     82 
     83         final Context context = getActivity();
     84 
     85         mIsPermittedToAdopt = UserManager.get(context).isAdminUser()
     86                 && !ActivityManager.isUserAMonkey();
     87 
     88         mStorageManager = context.getSystemService(StorageManager.class);
     89 
     90         if (DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS.equals(
     91                 getActivity().getIntent().getAction())) {
     92             final Uri rootUri = getActivity().getIntent().getData();
     93             final String fsUuid = DocumentsContract.getRootId(rootUri);
     94             mVolume = mStorageManager.findVolumeByUuid(fsUuid);
     95         } else {
     96             final String volId = getArguments().getString(VolumeInfo.EXTRA_VOLUME_ID);
     97             mVolume = mStorageManager.findVolumeById(volId);
     98         }
     99 
    100         if (!isVolumeValid()) {
    101             getActivity().finish();
    102             return;
    103         }
    104 
    105         mDisk = mStorageManager.findDiskById(mVolume.getDiskId());
    106         Preconditions.checkNotNull(mDisk);
    107 
    108         mVolumeId = mVolume.getId();
    109 
    110         addPreferencesFromResource(R.xml.device_info_storage_volume);
    111         getPreferenceScreen().setOrderingAsAdded(true);
    112 
    113         mSummary = new StorageSummaryPreference(context);
    114 
    115         mMount = buildAction(R.string.storage_menu_mount);
    116         mUnmount = buildAction(R.string.storage_menu_unmount);
    117         mFormatPublic = buildAction(R.string.storage_menu_format);
    118         if (mIsPermittedToAdopt) {
    119             mFormatPrivate = buildAction(R.string.storage_menu_format_private);
    120         }
    121     }
    122 
    123     public void update() {
    124         if (!isVolumeValid()) {
    125             getActivity().finish();
    126             return;
    127         }
    128 
    129         getActivity().setTitle(mStorageManager.getBestVolumeDescription(mVolume));
    130 
    131         final Context context = getActivity();
    132         final PreferenceScreen screen = getPreferenceScreen();
    133 
    134         screen.removeAll();
    135 
    136         if (mVolume.isMountedReadable()) {
    137             addPreference(mSummary);
    138 
    139             final File file = mVolume.getPath();
    140             final long totalBytes = file.getTotalSpace();
    141             final long freeBytes = file.getFreeSpace();
    142             final long usedBytes = totalBytes - freeBytes;
    143 
    144             final BytesResult result = Formatter.formatBytes(getResources(), usedBytes, 0);
    145             mSummary.setTitle(TextUtils.expandTemplate(getText(R.string.storage_size_large),
    146                     result.value, result.units));
    147             mSummary.setSummary(getString(R.string.storage_volume_used,
    148                     Formatter.formatFileSize(context, totalBytes)));
    149             mSummary.setPercent((int) ((usedBytes * 100) / totalBytes));
    150         }
    151 
    152         if (mVolume.getState() == VolumeInfo.STATE_UNMOUNTED) {
    153             addPreference(mMount);
    154         }
    155         if (mVolume.isMountedReadable()) {
    156             addPreference(mUnmount);
    157         }
    158         addPreference(mFormatPublic);
    159         if (mDisk.isAdoptable() && mIsPermittedToAdopt) {
    160             addPreference(mFormatPrivate);
    161         }
    162     }
    163 
    164     private void addPreference(Preference pref) {
    165         pref.setOrder(Preference.DEFAULT_ORDER);
    166         getPreferenceScreen().addPreference(pref);
    167     }
    168 
    169     private Preference buildAction(int titleRes) {
    170         final Preference pref = new Preference(getActivity());
    171         pref.setTitle(titleRes);
    172         return pref;
    173     }
    174 
    175     @Override
    176     public void onResume() {
    177         super.onResume();
    178 
    179         // Refresh to verify that we haven't been formatted away
    180         mVolume = mStorageManager.findVolumeById(mVolumeId);
    181         if (!isVolumeValid()) {
    182             getActivity().finish();
    183             return;
    184         }
    185 
    186         mStorageManager.registerListener(mStorageListener);
    187         update();
    188     }
    189 
    190     @Override
    191     public void onPause() {
    192         super.onPause();
    193         mStorageManager.unregisterListener(mStorageListener);
    194     }
    195 
    196     @Override
    197     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference pref) {
    198         final Context context = getActivity();
    199         if (pref == mMount) {
    200             new MountTask(context, mVolume).execute();
    201         } else if (pref == mUnmount) {
    202             new UnmountTask(context, mVolume).execute();
    203         } else if (pref == mFormatPublic) {
    204             final Intent intent = new Intent(context, StorageWizardFormatConfirm.class);
    205             intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
    206             intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false);
    207             startActivity(intent);
    208         } else if (pref == mFormatPrivate) {
    209             final Intent intent = new Intent(context, StorageWizardFormatConfirm.class);
    210             intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId());
    211             intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, true);
    212             startActivity(intent);
    213         }
    214 
    215         return super.onPreferenceTreeClick(preferenceScreen, pref);
    216     }
    217 
    218     private final StorageEventListener mStorageListener = new StorageEventListener() {
    219         @Override
    220         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
    221             if (Objects.equals(mVolume.getId(), vol.getId())) {
    222                 mVolume = vol;
    223                 update();
    224             }
    225         }
    226 
    227         @Override
    228         public void onVolumeRecordChanged(VolumeRecord rec) {
    229             if (Objects.equals(mVolume.getFsUuid(), rec.getFsUuid())) {
    230                 mVolume = mStorageManager.findVolumeById(mVolumeId);
    231                 update();
    232             }
    233         }
    234     };
    235 }
    236