Home | History | Annotate | Download | only in storage
      1 /*
      2  * Copyright (C) 2014 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.tv.settings.device.storage;
     18 
     19 import com.android.tv.settings.R;
     20 import com.android.tv.settings.device.storage.StorageMeasurement.MeasurementDetails;
     21 import com.android.tv.settings.device.storage.StorageMeasurement.MeasurementReceiver;
     22 import com.android.tv.settings.dialog.old.Action;
     23 import com.android.tv.settings.dialog.old.ActionAdapter;
     24 import com.android.tv.settings.dialog.old.ActionFragment;
     25 import com.android.tv.settings.dialog.old.ContentFragment;
     26 import com.android.tv.settings.dialog.old.DialogActivity;
     27 
     28 import android.app.Activity;
     29 import android.content.res.TypedArray;
     30 import android.graphics.Color;
     31 import android.os.Bundle;
     32 import android.os.Environment;
     33 import android.os.Handler;
     34 import android.os.Message;
     35 import android.text.format.Formatter;
     36 import android.widget.ImageView;
     37 import android.widget.TextView;
     38 
     39 import java.util.ArrayList;
     40 import java.util.Collections;
     41 import java.util.HashMap;
     42 import java.util.List;
     43 
     44 /**
     45  * Activity that shows storage information.
     46  */
     47 public class StorageActivity extends DialogActivity {
     48 
     49     private static final long INVALID_SIZE = -1;
     50 
     51     private static final int UPDATE_MSG = 1;
     52 
     53     private ActionFragment mActionFragment;
     54     private StorageContentFragment mContentFragment;
     55     private StorageMeasurement mMeasure;
     56     private boolean mResumed;
     57 
     58     private final MeasurementReceiver mReceiver = new MeasurementReceiver() {
     59 
     60         private long[] mLastApproximateDetails = null;
     61         private MeasurementDetails mLastMeasurementDetails = null;
     62 
     63         private final Handler mUpdateHandler = new Handler() {
     64             @Override
     65             public void handleMessage(Message msg) {
     66                 if (!mResumed) {
     67                     return;
     68                 }
     69                 switch (msg.what) {
     70                     case UPDATE_MSG:
     71                         if (mLastMeasurementDetails != null) {
     72                             StorageActivity.this.updateDetails(mLastMeasurementDetails);
     73                         } else if (mLastApproximateDetails != null) {
     74                             StorageActivity.this.updateApproximate(
     75                                     mLastApproximateDetails[0], mLastApproximateDetails[1]);
     76                         }
     77                         break;
     78                     default:
     79                         break;
     80                 }
     81             }
     82         };
     83 
     84         private void startUiUpdateTimer() {
     85             mUpdateHandler.sendEmptyMessageDelayed(UPDATE_MSG, 1000);
     86         }
     87 
     88         @Override
     89         public void updateApproximate(StorageMeasurement meas, long totalSize, long availSize) {
     90             mLastApproximateDetails = new long[] { totalSize, availSize };
     91             startUiUpdateTimer();
     92         }
     93 
     94         @Override
     95         public void updateDetails(StorageMeasurement meas, MeasurementDetails details) {
     96             mLastMeasurementDetails = details;
     97             startUiUpdateTimer();
     98         }
     99     };
    100 
    101     @Override
    102     protected void onCreate(Bundle savedInstanceState) {
    103         super.onCreate(savedInstanceState);
    104         mActionFragment = ActionFragment.newInstance(getActions());
    105         mContentFragment = StorageContentFragment.newInstance(getString(R.string.storage_title),
    106                 getString(R.string.header_category_device),
    107                 String.format(getString(R.string.storage_size), formatSize(INVALID_SIZE)),
    108                 R.drawable.ic_settings_storage, getResources().getColor(R.color.icon_background));
    109         setContentAndActionFragments(mContentFragment, mActionFragment);
    110         mMeasure = StorageMeasurement.getInstance(this, null);
    111     }
    112 
    113     @Override
    114     protected void onResume() {
    115         super.onResume();
    116         mResumed = true;
    117         mMeasure.setReceiver(mReceiver);
    118         mMeasure.invalidate();
    119         mMeasure.measure();
    120     }
    121 
    122     @Override
    123     protected void onPause() {
    124         mMeasure.cleanUp();
    125         mResumed = false;
    126         super.onPause();
    127     }
    128 
    129     private ArrayList<Action> getActions() {
    130         return getActions(INVALID_SIZE);
    131     }
    132 
    133     private ArrayList<Action> getActions(long availSize) {
    134         return getActions(availSize, INVALID_SIZE, INVALID_SIZE, INVALID_SIZE, INVALID_SIZE,
    135                 INVALID_SIZE, INVALID_SIZE);
    136     }
    137 
    138     private ArrayList<Action> getActions(long availSize, long appsSize, long dcimSize,
    139             long musicSize, long downloadsSize, long cacheSize, long miscSize) {
    140         ArrayList<Action> actions = new ArrayList<Action>();
    141         actions.add(StorageItem.APPS.toAction(getResources(), formatSize(appsSize)));
    142         actions.add(StorageItem.PICTURES_VIDEO.toAction(getResources(), formatSize(dcimSize)));
    143         actions.add(StorageItem.AUDIO.toAction(getResources(), formatSize(musicSize)));
    144         actions.add(StorageItem.DOWNLOADS.toAction(getResources(), formatSize(downloadsSize)));
    145         actions.add(StorageItem.CACHED_DATA.toAction(getResources(), formatSize(cacheSize)));
    146         actions.add(StorageItem.MISC.toAction(getResources(), formatSize(miscSize)));
    147         actions.add(StorageItem.AVAILABLE.toAction(getResources(), formatSize(availSize)));
    148         return actions;
    149     }
    150 
    151     private void updateActions(ArrayList<Action> actions) {
    152         ((ActionAdapter) mActionFragment.getAdapter()).setActions(actions);
    153     }
    154 
    155     private void updateApproximate(long totalSize, long availSize) {
    156 
    157         final long usedSize = totalSize - availSize;
    158 
    159         ArrayList<PercentageBarChart.Entry> entries = new ArrayList<PercentageBarChart.Entry>();
    160         entries.add(new PercentageBarChart.Entry(
    161                 0, usedSize / (float) totalSize, android.graphics.Color.GRAY));
    162 
    163         updateActions(getActions(availSize));
    164         updateStorageContentFragment(totalSize, entries);
    165     }
    166 
    167     private void updateDetails(MeasurementDetails details) {
    168 
    169         final long dcimSize = totalValues(details.mediaSize, Environment.DIRECTORY_DCIM,
    170                 Environment.DIRECTORY_MOVIES, Environment.DIRECTORY_PICTURES);
    171 
    172         final long musicSize = totalValues(details.mediaSize, Environment.DIRECTORY_MUSIC,
    173                 Environment.DIRECTORY_ALARMS, Environment.DIRECTORY_NOTIFICATIONS,
    174                 Environment.DIRECTORY_RINGTONES, Environment.DIRECTORY_PODCASTS);
    175 
    176         final long downloadsSize = totalValues(details.mediaSize, Environment.DIRECTORY_DOWNLOADS);
    177 
    178         ArrayList<PercentageBarChart.Entry> entries = new ArrayList<PercentageBarChart.Entry>();
    179 
    180         addEntry(entries, StorageItem.APPS, details.appsSize, details.totalSize);
    181         addEntry(entries, StorageItem.PICTURES_VIDEO, dcimSize, details.totalSize);
    182         addEntry(entries, StorageItem.AUDIO, musicSize, details.totalSize);
    183         addEntry(entries, StorageItem.DOWNLOADS, downloadsSize, details.totalSize);
    184         addEntry(entries, StorageItem.CACHED_DATA, details.cacheSize, details.totalSize);
    185         addEntry(entries, StorageItem.MISC, details.miscSize, details.totalSize);
    186 
    187         Collections.sort(entries);
    188 
    189         updateActions(getActions(
    190                 details.availSize, details.appsSize, dcimSize, musicSize, downloadsSize,
    191                 details.cacheSize, details.miscSize));
    192         updateStorageContentFragment(details.totalSize, entries);
    193     }
    194 
    195     private static long totalValues(HashMap<String, Long> map, String... keys) {
    196         long total = 0;
    197         for (String key : keys) {
    198             total += map.get(key);
    199         }
    200         return total;
    201     }
    202 
    203     private String formatSize(long size) {
    204         return (size == INVALID_SIZE) ? getString(R.string.storage_calculating_size)
    205                 : Formatter.formatShortFileSize(this, size);
    206     }
    207 
    208     private void addEntry(List<PercentageBarChart.Entry> entries, StorageItem storageItem,
    209             long size, long totalSize) {
    210         if (size > 0) {
    211             entries.add(new PercentageBarChart.Entry(
    212                     storageItem.ordinal(), size / (float) totalSize,
    213                     storageItem.getColor(getResources())));
    214         }
    215     }
    216 
    217     private void updateStorageContentFragment(long totalSize) {
    218         updateStorageContentFragment(totalSize, new ArrayList<PercentageBarChart.Entry>());
    219     }
    220 
    221     private void updateStorageContentFragment(
    222             long totalSize, ArrayList<PercentageBarChart.Entry> entries) {
    223         mContentFragment.updateEntries(entries);
    224         mContentFragment.setDescriptionText(
    225                 String.format(getString(R.string.storage_size), formatSize(totalSize)));
    226     }
    227 }
    228