OSDN Git Service

Merge "Use expander assets for bluetooth profile preference." into honeycomb
[android-x86/packages-apps-Settings.git] / src / com / android / settings / deviceinfo / Memory.java
index e22c39d..3e0f0a2 100644 (file)
@@ -18,6 +18,7 @@ package com.android.settings.deviceinfo;
 
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.deviceinfo.MemoryMeasurement.MeasurementReceiver;
 
 import android.app.ActivityManager;
 import android.app.AlertDialog;
@@ -30,30 +31,33 @@ import android.content.IntentFilter;
 import android.content.DialogInterface.OnCancelListener;
 import android.content.pm.ApplicationInfo;
 import android.content.res.Resources;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.RectShape;
+import android.graphics.drawable.shapes.RoundRectShape;
+import android.hardware.UsbManager;
 import android.os.Bundle;
-import android.hardware.Usb;
 import android.os.Environment;
+import android.os.Handler;
 import android.os.IBinder;
+import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.StatFs;
 import android.os.storage.IMountService;
 import android.os.storage.StorageEventListener;
 import android.os.storage.StorageManager;
-import android.preference.CheckBoxPreference;
 import android.preference.Preference;
+import android.preference.PreferenceGroup;
 import android.preference.PreferenceScreen;
-import android.provider.Settings;
 import android.text.format.Formatter;
 import android.util.Log;
 import android.widget.Toast;
 
-import java.io.File;
 import java.util.List;
 
-public class Memory extends SettingsPreferenceFragment implements OnCancelListener {
+public class Memory extends SettingsPreferenceFragment implements OnCancelListener,
+        MeasurementReceiver {
     private static final String TAG = "Memory";
-    private static final boolean localLOGV = false;
+    static final boolean localLOGV = false;
 
     private static final String MEMORY_SD_SIZE = "memory_sd_size";
 
@@ -63,24 +67,91 @@ public class Memory extends SettingsPreferenceFragment implements OnCancelListen
 
     private static final String MEMORY_SD_FORMAT = "memory_sd_format";
 
-    private static final String PTP_MODE_TOGGLE = "ptp_mode_toggle";
+    private static final String MEMORY_SD_GROUP = "memory_sd";
+
+    private static final String MEMORY_INTERNAL_SIZE = "memory_internal_size";
+
+    private static final String MEMORY_INTERNAL_AVAIL = "memory_internal_avail";
+
+    private static final String MEMORY_INTERNAL_APPS = "memory_internal_apps";
+
+    private static final String MEMORY_INTERNAL_MEDIA = "memory_internal_media";
+
+    private static final String MEMORY_INTERNAL_CHART = "memory_internal_chart";
 
     private static final int DLG_CONFIRM_UNMOUNT = 1;
     private static final int DLG_ERROR_UNMOUNT = 2;
 
     private Resources mRes;
 
+    // External storage preferences
     private Preference mSdSize;
     private Preference mSdAvail;
     private Preference mSdMountToggle;
     private Preference mSdFormat;
-    private CheckBoxPreference mPtpModeToggle;
+    private PreferenceGroup mSdMountPreferenceGroup;
+
+    // Internal storage preferences
+    private Preference mInternalSize;
+    private Preference mInternalAvail;
+    private Preference mInternalMediaUsage;
+    private Preference mInternalAppsUsage;
+    private UsageBarPreference mInternalUsageChart;
+
+    // Internal storage chart colors
+    private int mInternalMediaColor;
+    private int mInternalAppsColor;
+    private int mInternalUsedColor;
+
+    boolean mSdMountToggleAdded = true;
     
     // Access using getMountService()
     private IMountService mMountService = null;
 
     private StorageManager mStorageManager = null;
 
+    // Updates the memory usage bar graph.
+    private static final int MSG_UI_UPDATE_INTERNAL_APPROXIMATE = 1;
+
+    // Updates the memory usage bar graph.
+    private static final int MSG_UI_UPDATE_INTERNAL_EXACT = 2;
+
+    // Updates the memory usage stats for external.
+    private static final int MSG_UI_UPDATE_EXTERNAL_APPROXIMATE = 3;
+
+    private Handler mUpdateHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_UI_UPDATE_INTERNAL_APPROXIMATE: {
+                    Bundle bundle = msg.getData();
+                    final long totalSize = bundle.getLong(MemoryMeasurement.TOTAL_SIZE);
+                    final long availSize = bundle.getLong(MemoryMeasurement.AVAIL_SIZE);
+                    updateUiApproximate(totalSize, availSize);
+                    break;
+                }
+                case MSG_UI_UPDATE_INTERNAL_EXACT: {
+                    Bundle bundle = msg.getData();
+                    final long totalSize = bundle.getLong(MemoryMeasurement.TOTAL_SIZE);
+                    final long availSize = bundle.getLong(MemoryMeasurement.AVAIL_SIZE);
+                    final long mediaUsed = bundle.getLong(MemoryMeasurement.MEDIA_USED);
+                    final long appsUsed = bundle.getLong(MemoryMeasurement.APPS_USED);
+                    updateUiExact(totalSize, availSize, mediaUsed, appsUsed);
+                    break;
+                }
+                case MSG_UI_UPDATE_EXTERNAL_APPROXIMATE: {
+                    Bundle bundle = msg.getData();
+                    final long totalSize = bundle.getLong(MemoryMeasurement.TOTAL_SIZE);
+                    final long availSize = bundle.getLong(MemoryMeasurement.AVAIL_SIZE);
+                    updateExternalStorage(totalSize, availSize);
+                    break;
+                }
+            }
+        }
+    };
+
+    private MemoryMeasurement mMeasurement;
+
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -91,51 +162,83 @@ public class Memory extends SettingsPreferenceFragment implements OnCancelListen
         }
 
         addPreferencesFromResource(R.xml.device_info_memory);
-        
+
         mRes = getResources();
         mSdSize = findPreference(MEMORY_SD_SIZE);
         mSdAvail = findPreference(MEMORY_SD_AVAIL);
         mSdMountToggle = findPreference(MEMORY_SD_MOUNT_TOGGLE);
         mSdFormat = findPreference(MEMORY_SD_FORMAT);
+        mSdMountPreferenceGroup = (PreferenceGroup)findPreference(MEMORY_SD_GROUP);
 
-        mPtpModeToggle = (CheckBoxPreference)findPreference(PTP_MODE_TOGGLE);
-        if (Usb.isFunctionSupported(Usb.USB_FUNCTION_MTP)) {
-            mPtpModeToggle.setChecked(Settings.System.getInt(
-                    getContentResolver(),
-                    Settings.System.USE_PTP_INTERFACE, 0) != 0);
-        } else {
-            // hide the PTP mode toggle checkbox if MTP is not supported
-            getPreferenceScreen().removePreference(mPtpModeToggle);
+        if (Environment.isExternalStorageEmulated()) {
+            getPreferenceScreen().removePreference(mSdMountPreferenceGroup);
         }
+
+        mInternalSize = findPreference(MEMORY_INTERNAL_SIZE);
+        mInternalAvail = findPreference(MEMORY_INTERNAL_AVAIL);
+        mInternalMediaUsage = findPreference(MEMORY_INTERNAL_MEDIA);
+        mInternalAppsUsage = findPreference(MEMORY_INTERNAL_APPS);
+
+        mInternalMediaColor = mRes.getColor(R.color.memory_media_usage);
+        mInternalAppsColor = mRes.getColor(R.color.memory_apps_usage);
+        mInternalUsedColor = mRes.getColor(R.color.memory_used);
+
+        float[] radius = new float[] {
+                5f, 5f, 5f, 5f, 5f, 5f, 5f, 5f
+        };
+        RoundRectShape shape1 = new RoundRectShape(radius, null, null);
+
+        ShapeDrawable mediaShape = new ShapeDrawable(shape1);
+        mediaShape.setIntrinsicWidth(32);
+        mediaShape.setIntrinsicHeight(32);
+        mediaShape.getPaint().setColor(mInternalMediaColor);
+        mInternalMediaUsage.setIcon(mediaShape);
+
+        ShapeDrawable appsShape = new ShapeDrawable(shape1);
+        appsShape.setIntrinsicWidth(32);
+        appsShape.setIntrinsicHeight(32);
+        appsShape.getPaint().setColor(mInternalAppsColor);
+        mInternalAppsUsage.setIcon(appsShape);
+
+        mInternalUsageChart = (UsageBarPreference) findPreference(MEMORY_INTERNAL_CHART);
+
+        mMeasurement = MemoryMeasurement.getInstance(getActivity());
+        mMeasurement.setReceiver(this);
     }
-    
+
     @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(mReceiver, intentFilter);
 
-        updateMemoryStatus();
+        mMeasurement.invalidate();
+        if (!Environment.isExternalStorageEmulated()) {
+            mMeasurement.measureExternal();
+        }
+        mMeasurement.measureInternal();
     }
 
     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);
-            updateMemoryStatus();
+            if (!Environment.isExternalStorageEmulated()) {
+                mMeasurement.measureExternal();
+            }
         }
     };
-    
+
     @Override
     public void onPause() {
         super.onPause();
         getActivity().unregisterReceiver(mReceiver);
+        mMeasurement.cleanUp();
     }
 
     @Override
@@ -173,10 +276,11 @@ public class Memory extends SettingsPreferenceFragment implements OnCancelListen
             intent.setClass(getActivity(), com.android.settings.MediaFormat.class);
             startActivity(intent);
             return true;
-        } else if (preference == mPtpModeToggle) {
-            Settings.System.putInt(getContentResolver(),
-                    Settings.System.USE_PTP_INTERFACE,
-                    mPtpModeToggle.isChecked() ? 1 : 0);
+        } else if (preference == mInternalAppsUsage) {
+            Intent intent = new Intent(Intent.ACTION_MANAGE_PACKAGE_STORAGE);
+            intent.setClass(getActivity(),
+                    com.android.settings.Settings.ManageApplicationsActivity.class);
+            startActivity(intent);
             return true;
         }
 
@@ -186,7 +290,12 @@ public class Memory extends SettingsPreferenceFragment implements OnCancelListen
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            updateMemoryStatus();
+            mMeasurement.invalidate();
+
+            if (!Environment.isExternalStorageEmulated()) {
+                mMeasurement.measureExternal();
+            }
+            mMeasurement.measureInternal();
         }
     };
 
@@ -202,19 +311,29 @@ public class Memory extends SettingsPreferenceFragment implements OnCancelListen
                         }})
                     .setNegativeButton(R.string.cancel, null)
                     .setMessage(R.string.dlg_confirm_unmount_text)
-                    .setOnCancelListener(this)
                     .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)
-            .setOnCancelListener(this)
             .create();
         }
         return null;
     }
 
+    @Override
+    protected void showDialog(int id) {
+        super.showDialog(id);
+
+        switch (id) {
+        case DLG_CONFIRM_UNMOUNT:
+        case DLG_ERROR_UNMOUNT:
+            setOnCancelListener(this);
+            break;
+        }
+    }
+
     private void doUnmount(boolean force) {
         // Present a toast here
         Toast.makeText(getActivity(), R.string.unmount_inform_text, Toast.LENGTH_SHORT).show();
@@ -281,46 +400,84 @@ public class Memory extends SettingsPreferenceFragment implements OnCancelListen
         }
     }
 
-    private void updateMemoryStatus() {
+    private void updateUiExact(long totalSize, long availSize, long mediaSize, long appsSize) {
+        mInternalSize.setSummary(formatSize(totalSize));
+        mInternalAvail.setSummary(formatSize(availSize));
+        mInternalMediaUsage.setSummary(formatSize(mediaSize));
+        mInternalAppsUsage.setSummary(formatSize(appsSize));
+
+        mInternalUsageChart.clear();
+        mInternalUsageChart.addEntry(mediaSize / (float) totalSize, mInternalMediaColor);
+        mInternalUsageChart.addEntry(appsSize / (float) totalSize, mInternalAppsColor);
+
+        final long usedSize = totalSize - availSize;
+
+        // There are other things that can take up storage, but we didn't
+        // measure it.
+        final long remaining = usedSize - (mediaSize + appsSize);
+        if (remaining > 0) {
+            mInternalUsageChart.addEntry(remaining / (float) totalSize, mInternalUsedColor);
+        }
+        mInternalUsageChart.commit();
+    }
+
+    private void updateUiApproximate(long totalSize, long availSize) {
+        mInternalSize.setSummary(formatSize(totalSize));
+        mInternalAvail.setSummary(formatSize(availSize));
+
+        final long usedSize = totalSize - availSize;
+
+        mInternalUsageChart.clear();
+        mInternalUsageChart.addEntry(usedSize / (float) totalSize, mInternalUsedColor);
+        mInternalUsageChart.commit();
+    }
+
+    private void updateExternalStorage(long totalSize, long availSize) {
         String status = Environment.getExternalStorageState();
         String readOnly = "";
         if (status.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
             status = Environment.MEDIA_MOUNTED;
             readOnly = mRes.getString(R.string.read_only);
         }
-        mSdFormat.setEnabled(false);
 
         if (status.equals(Environment.MEDIA_MOUNTED)) {
+            if (!Environment.isExternalStorageRemovable()) {
+                // This device has built-in storage that is not removable.
+                // There is no reason for the user to unmount it.
+                if (mSdMountToggleAdded) {
+                    mSdMountPreferenceGroup.removePreference(mSdMountToggle);
+                    mSdMountToggleAdded = false;
+                }
+            }
             try {
-                File path = Environment.getExternalStorageDirectory();
-                StatFs stat = new StatFs(path.getPath());
-                long blockSize = stat.getBlockSize();
-                long totalBlocks = stat.getBlockCount();
-                long availableBlocks = stat.getAvailableBlocks();
-                
-                mSdSize.setSummary(formatSize(totalBlocks * blockSize));
-                mSdAvail.setSummary(formatSize(availableBlocks * blockSize) + readOnly);
+                mSdSize.setSummary(formatSize(totalSize));
+                mSdAvail.setSummary(formatSize(availSize) + readOnly);
 
                 mSdMountToggle.setEnabled(true);
                 mSdMountToggle.setTitle(mRes.getString(R.string.sd_eject));
                 mSdMountToggle.setSummary(mRes.getString(R.string.sd_eject_summary));
 
             } catch (IllegalArgumentException e) {
-                // this can occur if the SD card is removed, but we haven't received the 
+                // this can occur if the SD card is removed, but we haven't
+                // received the
                 // ACTION_MEDIA_REMOVED Intent yet.
                 status = Environment.MEDIA_REMOVED;
             }
-            
         } else {
             mSdSize.setSummary(mRes.getString(R.string.sd_unavailable));
             mSdAvail.setSummary(mRes.getString(R.string.sd_unavailable));
 
+            if (!Environment.isExternalStorageRemovable()) {
+                if (status.equals(Environment.MEDIA_UNMOUNTED)) {
+                    if (!mSdMountToggleAdded) {
+                        mSdMountPreferenceGroup.addPreference(mSdMountToggle);
+                        mSdMountToggleAdded = true;
+                    }
+                }
+            }
 
-            if (status.equals(Environment.MEDIA_UNMOUNTED) ||
-                status.equals(Environment.MEDIA_NOFS) ||
-                status.equals(Environment.MEDIA_UNMOUNTABLE) ) {
-                mSdFormat.setEnabled(true);
+            if (status.equals(Environment.MEDIA_UNMOUNTED) || status.equals(Environment.MEDIA_NOFS)
+                    || status.equals(Environment.MEDIA_UNMOUNTABLE)) {
                 mSdMountToggle.setEnabled(true);
                 mSdMountToggle.setTitle(mRes.getString(R.string.sd_mount));
                 mSdMountToggle.setSummary(mRes.getString(R.string.sd_mount_summary));
@@ -330,14 +487,8 @@ public class Memory extends SettingsPreferenceFragment implements OnCancelListen
                 mSdMountToggle.setSummary(mRes.getString(R.string.sd_insert_summary));
             }
         }
-
-        File path = Environment.getDataDirectory();
-        StatFs stat = new StatFs(path.getPath());
-        long blockSize = stat.getBlockSize();
-        long availableBlocks = stat.getAvailableBlocks();
-        findPreference("memory_internal_avail").setSummary(formatSize(availableBlocks * blockSize));
     }
-    
+
     private String formatSize(long size) {
         return Formatter.formatFileSize(getActivity(), size);
     }
@@ -346,5 +497,25 @@ public class Memory extends SettingsPreferenceFragment implements OnCancelListen
         // TODO: Is this really required?
         // finish();
     }
-    
+
+    @Override
+    public void updateApproximateExternal(Bundle bundle) {
+        final Message message = mUpdateHandler.obtainMessage(MSG_UI_UPDATE_EXTERNAL_APPROXIMATE);
+        message.setData(bundle);
+        mUpdateHandler.sendMessage(message);
+    }
+
+    @Override
+    public void updateApproximateInternal(Bundle bundle) {
+        final Message message = mUpdateHandler.obtainMessage(MSG_UI_UPDATE_INTERNAL_APPROXIMATE);
+        message.setData(bundle);
+        mUpdateHandler.sendMessage(message);
+    }
+
+    @Override
+    public void updateExactInternal(Bundle bundle) {
+        final Message message = mUpdateHandler.obtainMessage(MSG_UI_UPDATE_INTERNAL_EXACT);
+        message.setData(bundle);
+        mUpdateHandler.sendMessage(message);
+    }
 }