summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Zongker <dougz@android.com>2009-10-07 15:14:03 -0700
committerDoug Zongker <dougz@android.com>2009-10-07 17:16:07 -0700
commit3161795b2353171bb0636fb3ea6dab7dec80a4f4 (patch)
treec092a4e2e402b425f7f3a033fdfc5ebfc4aad2a3
parente9e1cdd556b40a04637b7de3d839b2a596df47e3 (diff)
downloadbase-3161795b2353171bb0636fb3ea6dab7dec80a4f4.tar.gz
when logging free space on /data, log /system and /cache as well
Report space free on system and cache so we can estimate bad block statistics for devices in the field.
-rw-r--r--services/java/com/android/server/DeviceStorageMonitorService.java104
1 files changed, 65 insertions, 39 deletions
diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java
index 52e09ca260a5..57af02953415 100644
--- a/services/java/com/android/server/DeviceStorageMonitorService.java
+++ b/services/java/com/android/server/DeviceStorageMonitorService.java
@@ -43,8 +43,8 @@ import android.provider.Settings;
/**
* This class implements a service to monitor the amount of disk storage space
* on the device. If the free storage on device is less than a tunable threshold value
- * (default is 10%. this value is a gservices parameter) a low memory notification is
- * displayed to alert the user. If the user clicks on the low memory notification the
+ * (default is 10%. this value is a gservices parameter) a low memory notification is
+ * displayed to alert the user. If the user clicks on the low memory notification the
* Application Manager application gets launched to let the user free storage space.
* Event log events:
* A low memory event with the free storage on device in bytes is logged to the event log
@@ -68,32 +68,35 @@ class DeviceStorageMonitorService extends Binder {
private static final int EVENT_LOG_FREE_STORAGE_LEFT = 2746;
private static final long DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD = 2 * 1024 * 1024; // 2MB
private static final long DEFAULT_CHECK_INTERVAL = MONITOR_INTERVAL*60*1000;
- private long mFreeMem;
+ private long mFreeMem; // on /data
private long mLastReportedFreeMem;
private long mLastReportedFreeMemTime;
private boolean mLowMemFlag=false;
private Context mContext;
private ContentResolver mContentResolver;
- long mBlkSize;
- long mTotalMemory;
- StatFs mFileStats;
- private static final String DATA_PATH="/data";
- long mThreadStartTime = -1;
- boolean mClearSucceeded = false;
- boolean mClearingCache;
+ private long mTotalMemory; // on /data
+ private StatFs mDataFileStats;
+ private StatFs mSystemFileStats;
+ private StatFs mCacheFileStats;
+ private static final String DATA_PATH = "/data";
+ private static final String SYSTEM_PATH = "/system";
+ private static final String CACHE_PATH = "/cache";
+ private long mThreadStartTime = -1;
+ private boolean mClearSucceeded = false;
+ private boolean mClearingCache;
private Intent mStorageLowIntent;
private Intent mStorageOkIntent;
private CachePackageDataObserver mClearCacheObserver;
private static final int _TRUE = 1;
private static final int _FALSE = 0;
-
+
/**
* This string is used for ServiceManager access to this class.
*/
static final String SERVICE = "devicestoragemonitor";
-
+
/**
- * Handler that checks the amount of disk space on the device and sends a
+ * Handler that checks the amount of disk space on the device and sends a
* notification if the device runs low on disk space
*/
Handler mHandler = new Handler() {
@@ -107,7 +110,7 @@ class DeviceStorageMonitorService extends Binder {
checkMemory(msg.arg1 == _TRUE);
}
};
-
+
class CachePackageDataObserver extends IPackageDataObserver.Stub {
public void onRemoveCompleted(String packageName, boolean succeeded) {
mClearSucceeded = succeeded;
@@ -115,12 +118,17 @@ class DeviceStorageMonitorService extends Binder {
if(localLOGV) Log.i(TAG, " Clear succeeded:"+mClearSucceeded
+", mClearingCache:"+mClearingCache+" Forcing memory check");
postCheckMemoryMsg(false, 0);
- }
+ }
}
-
+
private final void restatDataDir() {
- mFileStats.restat(DATA_PATH);
- mFreeMem = mFileStats.getAvailableBlocks()*mBlkSize;
+ try {
+ mDataFileStats.restat(DATA_PATH);
+ mFreeMem = (long) mDataFileStats.getAvailableBlocks() *
+ mDataFileStats.getBlockSize();
+ } catch (IllegalArgumentException e) {
+ // use the old value of mFreeMem
+ }
// Allow freemem to be overridden by debug.freemem for testing
String debugFreeMem = SystemProperties.get("debug.freemem");
if (!"".equals(debugFreeMem)) {
@@ -132,10 +140,27 @@ class DeviceStorageMonitorService extends Binder {
DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES)*60*1000;
//log the amount of free memory in event log
long currTime = SystemClock.elapsedRealtime();
- if((mLastReportedFreeMemTime == 0) ||
- (currTime-mLastReportedFreeMemTime) >= freeMemLogInterval) {
+ if((mLastReportedFreeMemTime == 0) ||
+ (currTime-mLastReportedFreeMemTime) >= freeMemLogInterval) {
mLastReportedFreeMemTime = currTime;
- EventLog.writeEvent(EVENT_LOG_FREE_STORAGE_LEFT, mFreeMem);
+ long mFreeSystem = -1, mFreeCache = -1;
+ try {
+ mSystemFileStats.restat(SYSTEM_PATH);
+ mFreeSystem = (long) mSystemFileStats.getAvailableBlocks() *
+ mSystemFileStats.getBlockSize();
+ } catch (IllegalArgumentException e) {
+ // ignore; report -1
+ }
+ try {
+ mCacheFileStats.restat(CACHE_PATH);
+ mFreeCache = (long) mCacheFileStats.getAvailableBlocks() *
+ mCacheFileStats.getBlockSize();
+ } catch (IllegalArgumentException e) {
+ // ignore; report -1
+ }
+ mCacheFileStats.restat(CACHE_PATH);
+ EventLog.writeEvent(EVENT_LOG_FREE_STORAGE_LEFT,
+ mFreeMem, mFreeSystem, mFreeCache);
}
// Read the reporting threshold from Gservices
long threshold = Gservices.getLong(mContentResolver,
@@ -148,7 +173,7 @@ class DeviceStorageMonitorService extends Binder {
EventLog.writeEvent(EVENT_LOG_STORAGE_BELOW_THRESHOLD, mFreeMem);
}
}
-
+
private final void clearCache() {
if (mClearCacheObserver == null) {
// Lazy instantiation
@@ -165,10 +190,10 @@ class DeviceStorageMonitorService extends Binder {
mClearSucceeded = false;
}
}
-
+
private final void checkMemory(boolean checkCache) {
- //if the thread that was started to clear cache is still running do nothing till its
- //finished clearing cache. Ideally this flag could be modified by clearCache
+ //if the thread that was started to clear cache is still running do nothing till its
+ //finished clearing cache. Ideally this flag could be modified by clearCache
// and should be accessed via a lock but even if it does this test will fail now and
//hopefully the next time this flag will be set to the correct value.
if(mClearingCache) {
@@ -177,11 +202,11 @@ class DeviceStorageMonitorService extends Binder {
long diffTime = System.currentTimeMillis() - mThreadStartTime;
if(diffTime > (10*60*1000)) {
Log.w(TAG, "Thread that clears cache file seems to run for ever");
- }
+ }
} else {
restatDataDir();
if (localLOGV) Log.v(TAG, "freeMemory="+mFreeMem);
-
+
//post intent to NotificationManager to display icon if necessary
long memThreshold = getMemThreshold();
if (mFreeMem < memThreshold) {
@@ -214,7 +239,7 @@ class DeviceStorageMonitorService extends Binder {
//keep posting messages to itself periodically
postCheckMemoryMsg(true, DEFAULT_CHECK_INTERVAL);
}
-
+
private void postCheckMemoryMsg(boolean clearCache, long delay) {
// Remove queued messages
mHandler.removeMessages(DEVICE_MEMORY_WHAT);
@@ -222,16 +247,16 @@ class DeviceStorageMonitorService extends Binder {
clearCache ?_TRUE : _FALSE, 0),
delay);
}
-
+
/*
- * just query settings to retrieve the memory threshold.
+ * just query settings to retrieve the memory threshold.
* Preferred this over using a ContentObserver since Settings.Gservices caches the value
* any way
*/
private long getMemThreshold() {
int value = Settings.Gservices.getInt(
- mContentResolver,
- Settings.Gservices.SYS_STORAGE_THRESHOLD_PERCENTAGE,
+ mContentResolver,
+ Settings.Gservices.SYS_STORAGE_THRESHOLD_PERCENTAGE,
DEFAULT_THRESHOLD_PERCENTAGE);
if(localLOGV) Log.v(TAG, "Threshold Percentage="+value);
//evaluate threshold value
@@ -247,16 +272,17 @@ class DeviceStorageMonitorService extends Binder {
mContext = context;
mContentResolver = mContext.getContentResolver();
//create StatFs object
- mFileStats = new StatFs(DATA_PATH);
- //initialize block size
- mBlkSize = mFileStats.getBlockSize();
+ mDataFileStats = new StatFs(DATA_PATH);
+ mSystemFileStats = new StatFs(SYSTEM_PATH);
+ mCacheFileStats = new StatFs(CACHE_PATH);
//initialize total storage on device
- mTotalMemory = ((long)mFileStats.getBlockCount()*mBlkSize)/100L;
+ mTotalMemory = ((long)mDataFileStats.getBlockCount() *
+ mDataFileStats.getBlockSize())/100L;
mStorageLowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_LOW);
mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK);
checkMemory(true);
}
-
+
/**
* This method sends a notification to NotificationManager to display
@@ -271,7 +297,7 @@ class DeviceStorageMonitorService extends Binder {
Intent lowMemIntent = new Intent(Intent.ACTION_MANAGE_PACKAGE_STORAGE);
lowMemIntent.putExtra("memory", mFreeMem);
lowMemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- NotificationManager mNotificationMgr =
+ NotificationManager mNotificationMgr =
(NotificationManager)mContext.getSystemService(
Context.NOTIFICATION_SERVICE);
CharSequence title = mContext.getText(
@@ -302,7 +328,7 @@ class DeviceStorageMonitorService extends Binder {
mContext.removeStickyBroadcast(mStorageLowIntent);
mContext.sendBroadcast(mStorageOkIntent);
}
-
+
public void updateMemory() {
int callingUid = getCallingUid();
if(callingUid != Process.SYSTEM_UID) {