Loading core/java/android/content/Intent.java +24 −0 Original line number Diff line number Diff line Loading @@ -1566,6 +1566,30 @@ public class Intent implements Parcelable, Cloneable { */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK"; /** * Broadcast Action: A sticky broadcast that indicates a memory full * condition on the device. This is intended for activities that want * to be able to fill the data partition completely, leaving only * enough free space to prevent system-wide SQLite failures. * * <p class="note">This is a protected intent that can only be sent * by the system. * * {@hide} */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_DEVICE_STORAGE_FULL = "android.intent.action.DEVICE_STORAGE_FULL"; /** * Broadcast Action: Indicates memory full condition on the device * no longer exists. * * <p class="note">This is a protected intent that can only be sent * by the system. * * {@hide} */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_DEVICE_STORAGE_NOT_FULL = "android.intent.action.DEVICE_STORAGE_NOT_FULL"; /** * Broadcast Action: Indicates low memory condition notification acknowledged by user * and package management should be started. Loading core/java/android/provider/Settings.java +14 −5 Original line number Diff line number Diff line Loading @@ -2961,31 +2961,31 @@ public final class Settings { public static final String WTF_IS_FATAL = "wtf_is_fatal"; /** * Maximum age of entries kept by {@link android.os.IDropBox}. * Maximum age of entries kept by {@link com.android.internal.os.IDropBoxManagerService}. * @hide */ public static final String DROPBOX_AGE_SECONDS = "dropbox_age_seconds"; /** * Maximum number of entry files which {@link android.os.IDropBox} will keep around. * Maximum number of entry files which {@link com.android.internal.os.IDropBoxManagerService} will keep around. * @hide */ public static final String DROPBOX_MAX_FILES = "dropbox_max_files"; /** * Maximum amount of disk space used by {@link android.os.IDropBox} no matter what. * Maximum amount of disk space used by {@link com.android.internal.os.IDropBoxManagerService} no matter what. * @hide */ public static final String DROPBOX_QUOTA_KB = "dropbox_quota_kb"; /** * Percent of free disk (excluding reserve) which {@link android.os.IDropBox} will use. * Percent of free disk (excluding reserve) which {@link com.android.internal.os.IDropBoxManagerService} will use. * @hide */ public static final String DROPBOX_QUOTA_PERCENT = "dropbox_quota_percent"; /** * Percent of total disk which {@link android.os.IDropBox} will never dip into. * Percent of total disk which {@link com.android.internal.os.IDropBoxManagerService} will never dip into. * @hide */ public static final String DROPBOX_RESERVE_PERCENT = Loading Loading @@ -3044,6 +3044,15 @@ public final class Settings { public static final String SYS_STORAGE_THRESHOLD_PERCENTAGE = "sys_storage_threshold_percentage"; /** * Minimum bytes of free storage on the device before the data * partition is considered full. By default, 1 MB is reserved * to avoid system-wide SQLite disk full exceptions. * @hide */ public static final String SYS_STORAGE_FULL_THRESHOLD_BYTES = "sys_storage_full_threshold_bytes"; /** * The interval in milliseconds after which Wi-Fi is considered idle. * When idle, it is possible for the device to be switched from Wi-Fi to Loading core/res/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ <protected-broadcast android:name="android.intent.action.ACTION_SHUTDOWN" /> <protected-broadcast android:name="android.intent.action.DEVICE_STORAGE_LOW" /> <protected-broadcast android:name="android.intent.action.DEVICE_STORAGE_OK" /> <protected-broadcast android:name="android.intent.action.DEVICE_STORAGE_FULL" /> <protected-broadcast android:name="android.intent.action.DEVICE_STORAGE_NOT_FULL" /> <protected-broadcast android:name="android.intent.action.NEW_OUTGOING_CALL" /> <protected-broadcast android:name="android.intent.action.REBOOT" /> <protected-broadcast android:name="android.intent.action.DOCK_EVENT" /> Loading services/java/com/android/server/DeviceStorageMonitorService.java +58 −4 Original line number Diff line number Diff line Loading @@ -69,10 +69,12 @@ class DeviceStorageMonitorService extends Binder { private static final int DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES = 12*60; //in minutes 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 static final int DEFAULT_FULL_THRESHOLD_BYTES = 1024*1024; // 1MB private long mFreeMem; // on /data private long mLastReportedFreeMem; private long mLastReportedFreeMemTime; private boolean mLowMemFlag=false; private boolean mMemFullFlag=false; private Context mContext; private ContentResolver mContentResolver; private long mTotalMemory; // on /data Loading @@ -87,9 +89,13 @@ class DeviceStorageMonitorService extends Binder { private boolean mClearingCache; private Intent mStorageLowIntent; private Intent mStorageOkIntent; private Intent mStorageFullIntent; private Intent mStorageNotFullIntent; private CachePackageDataObserver mClearCacheObserver; private static final int _TRUE = 1; private static final int _FALSE = 0; private long mMemLowThreshold; private int mMemFullThreshold; /** * This string is used for ServiceManager access to this class. Loading @@ -103,7 +109,7 @@ class DeviceStorageMonitorService extends Binder { Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { //dont handle an invalid message //don't handle an invalid message if (msg.what != DEVICE_MEMORY_WHAT) { Slog.e(TAG, "Will not process invalid message"); return; Loading Loading @@ -184,7 +190,7 @@ class DeviceStorageMonitorService extends Binder { try { if (localLOGV) Slog.i(TAG, "Clearing cache"); IPackageManager.Stub.asInterface(ServiceManager.getService("package")). freeStorageAndNotify(getMemThreshold(), mClearCacheObserver); freeStorageAndNotify(mMemLowThreshold, mClearCacheObserver); } catch (RemoteException e) { Slog.w(TAG, "Failed to get handle for PackageManger Exception: "+e); mClearingCache = false; Loading @@ -209,8 +215,7 @@ class DeviceStorageMonitorService extends Binder { if (localLOGV) Slog.v(TAG, "freeMemory="+mFreeMem); //post intent to NotificationManager to display icon if necessary long memThreshold = getMemThreshold(); if (mFreeMem < memThreshold) { if (mFreeMem < mMemLowThreshold) { if (!mLowMemFlag) { if (checkCache) { // See if clearing cache helps Loading @@ -235,6 +240,17 @@ class DeviceStorageMonitorService extends Binder { mLowMemFlag = false; } } if (mFreeMem < mMemFullThreshold) { if (!mMemFullFlag) { sendFullNotification(); mMemFullFlag = true; } } else { if (mMemFullFlag) { cancelFullNotification(); mMemFullFlag = false; } } } if(localLOGV) Slog.i(TAG, "Posting Message again"); //keep posting messages to itself periodically Loading Loading @@ -264,6 +280,20 @@ class DeviceStorageMonitorService extends Binder { return mTotalMemory*value; } /* * just query settings to retrieve the memory full threshold. * Preferred this over using a ContentObserver since Settings.Secure caches the value * any way */ private int getMemFullThreshold() { int value = Settings.Secure.getInt( mContentResolver, Settings.Secure.SYS_STORAGE_FULL_THRESHOLD_BYTES, DEFAULT_FULL_THRESHOLD_BYTES); if(localLOGV) Slog.v(TAG, "Full Threshold Bytes="+value); return value; } /** * Constructor to run service. initializes the disk space threshold value * and posts an empty message to kickstart the process. Loading @@ -283,6 +313,13 @@ class DeviceStorageMonitorService extends Binder { mStorageLowIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK); mStorageOkIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mStorageFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_FULL); mStorageFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mStorageNotFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL); mStorageNotFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); // cache storage thresholds mMemLowThreshold = getMemThreshold(); mMemFullThreshold = getMemFullThreshold(); checkMemory(true); } Loading Loading @@ -332,6 +369,23 @@ class DeviceStorageMonitorService extends Binder { mContext.sendBroadcast(mStorageOkIntent); } /** * Send a notification when storage is full. */ private final void sendFullNotification() { if(localLOGV) Slog.i(TAG, "Sending memory full notification"); mContext.sendStickyBroadcast(mStorageFullIntent); } /** * Cancels memory full notification and sends "not full" intent. */ private final void cancelFullNotification() { if(localLOGV) Slog.i(TAG, "Canceling memory full notification"); mContext.removeStickyBroadcast(mStorageFullIntent); mContext.sendBroadcast(mStorageNotFullIntent); } public void updateMemory() { int callingUid = getCallingUid(); if(callingUid != Process.SYSTEM_UID) { Loading telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java +4 −4 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * @param destPort the port to deliver the message to * @param data the body of the message to send * @param sentIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is sucessfully sent, or failed. * broadcast when the message is successfully sent, or failed. * The result code will be <code>Activity.RESULT_OK<code> for success, * or one of these errors:<br> * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> Loading @@ -67,7 +67,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * the extra "errorCode" containing a radio technology specific value, * generally only useful for troubleshooting.<br> * The per-application based SMS control checks sentIntent. If sentIntent * is NULL the caller will be checked against all unknown applicaitons, * is NULL the caller will be checked against all unknown applications, * which cause smaller number of SMS to be sent in checking period. * @param deliveryIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is delivered to the recipient. The Loading @@ -94,7 +94,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * the current default SMSC * @param text the body of the message to send * @param sentIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is sucessfully sent, or failed. * broadcast when the message is successfully sent, or failed. * The result code will be <code>Activity.RESULT_OK<code> for success, * or one of these errors:<br> * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> Loading Loading @@ -140,7 +140,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * <code>RESULT_ERROR_RADIO_OFF</code> * <code>RESULT_ERROR_NULL_PDU</code>. * The per-application based SMS control checks sentIntent. If sentIntent * is NULL the caller will be checked against all unknown applicaitons, * is NULL the caller will be checked against all unknown applications, * which cause smaller number of SMS to be sent in checking period. * @param deliveryIntents if not null, an <code>ArrayList</code> of * <code>PendingIntent</code>s (one for each message part) that is Loading Loading
core/java/android/content/Intent.java +24 −0 Original line number Diff line number Diff line Loading @@ -1566,6 +1566,30 @@ public class Intent implements Parcelable, Cloneable { */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK"; /** * Broadcast Action: A sticky broadcast that indicates a memory full * condition on the device. This is intended for activities that want * to be able to fill the data partition completely, leaving only * enough free space to prevent system-wide SQLite failures. * * <p class="note">This is a protected intent that can only be sent * by the system. * * {@hide} */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_DEVICE_STORAGE_FULL = "android.intent.action.DEVICE_STORAGE_FULL"; /** * Broadcast Action: Indicates memory full condition on the device * no longer exists. * * <p class="note">This is a protected intent that can only be sent * by the system. * * {@hide} */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_DEVICE_STORAGE_NOT_FULL = "android.intent.action.DEVICE_STORAGE_NOT_FULL"; /** * Broadcast Action: Indicates low memory condition notification acknowledged by user * and package management should be started. Loading
core/java/android/provider/Settings.java +14 −5 Original line number Diff line number Diff line Loading @@ -2961,31 +2961,31 @@ public final class Settings { public static final String WTF_IS_FATAL = "wtf_is_fatal"; /** * Maximum age of entries kept by {@link android.os.IDropBox}. * Maximum age of entries kept by {@link com.android.internal.os.IDropBoxManagerService}. * @hide */ public static final String DROPBOX_AGE_SECONDS = "dropbox_age_seconds"; /** * Maximum number of entry files which {@link android.os.IDropBox} will keep around. * Maximum number of entry files which {@link com.android.internal.os.IDropBoxManagerService} will keep around. * @hide */ public static final String DROPBOX_MAX_FILES = "dropbox_max_files"; /** * Maximum amount of disk space used by {@link android.os.IDropBox} no matter what. * Maximum amount of disk space used by {@link com.android.internal.os.IDropBoxManagerService} no matter what. * @hide */ public static final String DROPBOX_QUOTA_KB = "dropbox_quota_kb"; /** * Percent of free disk (excluding reserve) which {@link android.os.IDropBox} will use. * Percent of free disk (excluding reserve) which {@link com.android.internal.os.IDropBoxManagerService} will use. * @hide */ public static final String DROPBOX_QUOTA_PERCENT = "dropbox_quota_percent"; /** * Percent of total disk which {@link android.os.IDropBox} will never dip into. * Percent of total disk which {@link com.android.internal.os.IDropBoxManagerService} will never dip into. * @hide */ public static final String DROPBOX_RESERVE_PERCENT = Loading Loading @@ -3044,6 +3044,15 @@ public final class Settings { public static final String SYS_STORAGE_THRESHOLD_PERCENTAGE = "sys_storage_threshold_percentage"; /** * Minimum bytes of free storage on the device before the data * partition is considered full. By default, 1 MB is reserved * to avoid system-wide SQLite disk full exceptions. * @hide */ public static final String SYS_STORAGE_FULL_THRESHOLD_BYTES = "sys_storage_full_threshold_bytes"; /** * The interval in milliseconds after which Wi-Fi is considered idle. * When idle, it is possible for the device to be switched from Wi-Fi to Loading
core/res/AndroidManifest.xml +2 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ <protected-broadcast android:name="android.intent.action.ACTION_SHUTDOWN" /> <protected-broadcast android:name="android.intent.action.DEVICE_STORAGE_LOW" /> <protected-broadcast android:name="android.intent.action.DEVICE_STORAGE_OK" /> <protected-broadcast android:name="android.intent.action.DEVICE_STORAGE_FULL" /> <protected-broadcast android:name="android.intent.action.DEVICE_STORAGE_NOT_FULL" /> <protected-broadcast android:name="android.intent.action.NEW_OUTGOING_CALL" /> <protected-broadcast android:name="android.intent.action.REBOOT" /> <protected-broadcast android:name="android.intent.action.DOCK_EVENT" /> Loading
services/java/com/android/server/DeviceStorageMonitorService.java +58 −4 Original line number Diff line number Diff line Loading @@ -69,10 +69,12 @@ class DeviceStorageMonitorService extends Binder { private static final int DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES = 12*60; //in minutes 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 static final int DEFAULT_FULL_THRESHOLD_BYTES = 1024*1024; // 1MB private long mFreeMem; // on /data private long mLastReportedFreeMem; private long mLastReportedFreeMemTime; private boolean mLowMemFlag=false; private boolean mMemFullFlag=false; private Context mContext; private ContentResolver mContentResolver; private long mTotalMemory; // on /data Loading @@ -87,9 +89,13 @@ class DeviceStorageMonitorService extends Binder { private boolean mClearingCache; private Intent mStorageLowIntent; private Intent mStorageOkIntent; private Intent mStorageFullIntent; private Intent mStorageNotFullIntent; private CachePackageDataObserver mClearCacheObserver; private static final int _TRUE = 1; private static final int _FALSE = 0; private long mMemLowThreshold; private int mMemFullThreshold; /** * This string is used for ServiceManager access to this class. Loading @@ -103,7 +109,7 @@ class DeviceStorageMonitorService extends Binder { Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { //dont handle an invalid message //don't handle an invalid message if (msg.what != DEVICE_MEMORY_WHAT) { Slog.e(TAG, "Will not process invalid message"); return; Loading Loading @@ -184,7 +190,7 @@ class DeviceStorageMonitorService extends Binder { try { if (localLOGV) Slog.i(TAG, "Clearing cache"); IPackageManager.Stub.asInterface(ServiceManager.getService("package")). freeStorageAndNotify(getMemThreshold(), mClearCacheObserver); freeStorageAndNotify(mMemLowThreshold, mClearCacheObserver); } catch (RemoteException e) { Slog.w(TAG, "Failed to get handle for PackageManger Exception: "+e); mClearingCache = false; Loading @@ -209,8 +215,7 @@ class DeviceStorageMonitorService extends Binder { if (localLOGV) Slog.v(TAG, "freeMemory="+mFreeMem); //post intent to NotificationManager to display icon if necessary long memThreshold = getMemThreshold(); if (mFreeMem < memThreshold) { if (mFreeMem < mMemLowThreshold) { if (!mLowMemFlag) { if (checkCache) { // See if clearing cache helps Loading @@ -235,6 +240,17 @@ class DeviceStorageMonitorService extends Binder { mLowMemFlag = false; } } if (mFreeMem < mMemFullThreshold) { if (!mMemFullFlag) { sendFullNotification(); mMemFullFlag = true; } } else { if (mMemFullFlag) { cancelFullNotification(); mMemFullFlag = false; } } } if(localLOGV) Slog.i(TAG, "Posting Message again"); //keep posting messages to itself periodically Loading Loading @@ -264,6 +280,20 @@ class DeviceStorageMonitorService extends Binder { return mTotalMemory*value; } /* * just query settings to retrieve the memory full threshold. * Preferred this over using a ContentObserver since Settings.Secure caches the value * any way */ private int getMemFullThreshold() { int value = Settings.Secure.getInt( mContentResolver, Settings.Secure.SYS_STORAGE_FULL_THRESHOLD_BYTES, DEFAULT_FULL_THRESHOLD_BYTES); if(localLOGV) Slog.v(TAG, "Full Threshold Bytes="+value); return value; } /** * Constructor to run service. initializes the disk space threshold value * and posts an empty message to kickstart the process. Loading @@ -283,6 +313,13 @@ class DeviceStorageMonitorService extends Binder { mStorageLowIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK); mStorageOkIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mStorageFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_FULL); mStorageFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mStorageNotFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL); mStorageNotFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); // cache storage thresholds mMemLowThreshold = getMemThreshold(); mMemFullThreshold = getMemFullThreshold(); checkMemory(true); } Loading Loading @@ -332,6 +369,23 @@ class DeviceStorageMonitorService extends Binder { mContext.sendBroadcast(mStorageOkIntent); } /** * Send a notification when storage is full. */ private final void sendFullNotification() { if(localLOGV) Slog.i(TAG, "Sending memory full notification"); mContext.sendStickyBroadcast(mStorageFullIntent); } /** * Cancels memory full notification and sends "not full" intent. */ private final void cancelFullNotification() { if(localLOGV) Slog.i(TAG, "Canceling memory full notification"); mContext.removeStickyBroadcast(mStorageFullIntent); mContext.sendBroadcast(mStorageNotFullIntent); } public void updateMemory() { int callingUid = getCallingUid(); if(callingUid != Process.SYSTEM_UID) { Loading
telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java +4 −4 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * @param destPort the port to deliver the message to * @param data the body of the message to send * @param sentIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is sucessfully sent, or failed. * broadcast when the message is successfully sent, or failed. * The result code will be <code>Activity.RESULT_OK<code> for success, * or one of these errors:<br> * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> Loading @@ -67,7 +67,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * the extra "errorCode" containing a radio technology specific value, * generally only useful for troubleshooting.<br> * The per-application based SMS control checks sentIntent. If sentIntent * is NULL the caller will be checked against all unknown applicaitons, * is NULL the caller will be checked against all unknown applications, * which cause smaller number of SMS to be sent in checking period. * @param deliveryIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is delivered to the recipient. The Loading @@ -94,7 +94,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * the current default SMSC * @param text the body of the message to send * @param sentIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is sucessfully sent, or failed. * broadcast when the message is successfully sent, or failed. * The result code will be <code>Activity.RESULT_OK<code> for success, * or one of these errors:<br> * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> Loading Loading @@ -140,7 +140,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * <code>RESULT_ERROR_RADIO_OFF</code> * <code>RESULT_ERROR_NULL_PDU</code>. * The per-application based SMS control checks sentIntent. If sentIntent * is NULL the caller will be checked against all unknown applicaitons, * is NULL the caller will be checked against all unknown applications, * which cause smaller number of SMS to be sent in checking period. * @param deliveryIntents if not null, an <code>ArrayList</code> of * <code>PendingIntent</code>s (one for each message part) that is Loading