diff options
9 files changed, 112 insertions, 26 deletions
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 359eaaaf54bf..4d0b8b06905d 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1577,6 +1577,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. * This is triggered by the user from the ACTION_DEVICE_STORAGE_LOW diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index dcd1d949f922..567ee937ef20 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3005,31 +3005,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 = @@ -3089,6 +3089,15 @@ public final class Settings { "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 * the mobile data network. diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index c7c8ec198d73..89298eaf5225 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -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" /> diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java index 4a0df597ccaf..0b1a4a3ee314 100644 --- a/services/java/com/android/server/DeviceStorageMonitorService.java +++ b/services/java/com/android/server/DeviceStorageMonitorService.java @@ -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 @@ -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. @@ -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; @@ -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; @@ -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 @@ -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 @@ -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. @@ -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); } @@ -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) { diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java index f1a710744fcb..3a7ce479f188 100644 --- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java @@ -32,9 +32,11 @@ import android.database.Cursor; import android.database.SQLException; import android.net.Uri; import android.os.AsyncResult; +import android.os.Environment; import android.os.Handler; import android.os.Message; import android.os.PowerManager; +import android.os.StatFs; import android.provider.Telephony; import android.provider.Telephony.Sms.Intents; import android.provider.Settings; @@ -240,11 +242,9 @@ public abstract class SMSDispatcher extends Handler { // Register for device storage intents. Use these to notify the RIL // that storage for SMS is or is not available. - // TODO: Revisit this for a later release. Storage reporting should - // rely more on application indication. IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW); - filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); + filter.addAction(Intent.ACTION_DEVICE_STORAGE_FULL); + filter.addAction(Intent.ACTION_DEVICE_STORAGE_NOT_FULL); mContext.registerReceiver(mResultReceiver, filter); } @@ -966,10 +966,10 @@ public abstract class SMSDispatcher extends Handler { private BroadcastReceiver mResultReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_LOW)) { + if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_FULL)) { mStorageAvailable = false; mCm.reportSmsMemoryStatus(false, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE)); - } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_OK)) { + } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)) { mStorageAvailable = true; mCm.reportSmsMemoryStatus(true, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE)); } else { diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java index 47a170a36848..6e53ec5b458f 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java @@ -101,7 +101,6 @@ public class CDMAPhone extends PhoneBase { CdmaCallTracker mCT; CdmaSMSDispatcher mSMS; CdmaServiceStateTracker mSST; - RuimFileHandler mRuimFileHandler; RuimRecords mRuimRecords; RuimCard mRuimCard; ArrayList <CdmaMmiCode> mPendingMmis = new ArrayList<CdmaMmiCode>(); @@ -159,7 +158,7 @@ public class CDMAPhone extends PhoneBase { mDataConnection = new CdmaDataConnectionTracker (this); mRuimCard = new RuimCard(this); mRuimPhoneBookInterfaceManager = new RuimPhoneBookInterfaceManager(this); - mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this); + mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this, mSMS); mSubInfo = new PhoneSubInfo(this); mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML); mCcatService = CatService.getInstance(mCM, mRuimRecords, mContext, diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java index a9df375b58f8..d84b6ab26e9c 100644 --- a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java +++ b/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java @@ -27,6 +27,7 @@ import com.android.internal.telephony.IccConstants; import com.android.internal.telephony.IccSmsInterfaceManager; import com.android.internal.telephony.IccUtils; import com.android.internal.telephony.PhoneProxy; +import com.android.internal.telephony.SMSDispatcher; import com.android.internal.telephony.SmsRawData; import java.util.ArrayList; @@ -80,9 +81,9 @@ public class RuimSmsInterfaceManager extends IccSmsInterfaceManager { } }; - public RuimSmsInterfaceManager(CDMAPhone phone) { + public RuimSmsInterfaceManager(CDMAPhone phone, SMSDispatcher dispatcher) { super(phone); - mDispatcher = new CdmaSMSDispatcher(phone); + mDispatcher = dispatcher; } public void dispose() { diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java index d64541b0acfc..30a632447f4a 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java +++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java @@ -117,10 +117,6 @@ public class GSMPhone extends PhoneBase { Thread debugPortThread; ServerSocket debugSocket; - private int mReportedRadioResets; - private int mReportedAttemptedConnects; - private int mReportedSuccessfulConnects; - private String mImei; private String mImeiSv; private String mVmNumber; @@ -151,7 +147,7 @@ public class GSMPhone extends PhoneBase { mSimCard = new SimCard(this); if (!unitTestMode) { mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this); - mSimSmsIntManager = new SimSmsInterfaceManager(this); + mSimSmsIntManager = new SimSmsInterfaceManager(this, mSMS); mSubInfo = new PhoneSubInfo(this); } mStkService = CatService.getInstance(mCM, mSIMRecords, mContext, diff --git a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java index f000d7901bea..aab359fcbe33 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java +++ b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java @@ -25,6 +25,7 @@ import android.util.Log; import com.android.internal.telephony.IccConstants; import com.android.internal.telephony.IccSmsInterfaceManager; import com.android.internal.telephony.IccUtils; +import com.android.internal.telephony.SMSDispatcher; import com.android.internal.telephony.SmsRawData; import java.util.ArrayList; @@ -78,9 +79,9 @@ public class SimSmsInterfaceManager extends IccSmsInterfaceManager { } }; - public SimSmsInterfaceManager(GSMPhone phone) { + public SimSmsInterfaceManager(GSMPhone phone, SMSDispatcher dispatcher) { super(phone); - mDispatcher = new GsmSMSDispatcher(phone); + mDispatcher = dispatcher; } public void dispose() { |