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;
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.PreferenceActivity;
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;
private static final String MEMORY_SD_GROUP = "memory_sd";
- private static final String PTP_MODE_TOGGLE = "ptp_mode_toggle";
+ 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 PreferenceGroup mSdMountPreferenceGroup;
- boolean mSdMountToggleAdded = true;
+ // 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;
- private CheckBoxPreference mPtpModeToggle;
+ 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);
}
addPreferencesFromResource(R.xml.device_info_memory);
-
+
mRes = getResources();
mSdSize = findPreference(MEMORY_SD_SIZE);
mSdAvail = findPreference(MEMORY_SD_AVAIL);
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()) {
+ mSdMountPreferenceGroup.removePreference(mSdSize);
+ mSdMountPreferenceGroup.removePreference(mSdAvail);
+ mSdMountPreferenceGroup.removePreference(mSdMountToggle);
}
+
+ 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();
+ 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
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);
- return true;
}
return false;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- updateMemoryStatus();
+ mMeasurement.invalidate();
+
+ if (!Environment.isExternalStorageEmulated()) {
+ mMeasurement.measureExternal();
+ }
+ mMeasurement.measureInternal();
}
};
}
}
- 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);
}
-
+
if (status.equals(Environment.MEDIA_MOUNTED)) {
if (!Environment.isExternalStorageRemovable()) {
// This device has built-in storage that is not removable.
}
}
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) {
}
}
- if (status.equals(Environment.MEDIA_UNMOUNTED) ||
- status.equals(Environment.MEDIA_NOFS) ||
- status.equals(Environment.MEDIA_UNMOUNTABLE) ) {
+ 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));
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);
}
// 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);
+ }
}