blob: d34087f959d0725a664af2ab092e40898fb801ba [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server;
18
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019import android.app.Notification;
20import android.app.NotificationManager;
21import android.app.PendingIntent;
22import android.content.ContentResolver;
23import android.content.Context;
24import android.content.Intent;
25import android.content.pm.IPackageDataObserver;
26import android.content.pm.IPackageManager;
27import android.os.Binder;
28import android.os.Handler;
29import android.os.Message;
30import android.os.Process;
31import android.os.RemoteException;
32import android.os.ServiceManager;
33import android.os.StatFs;
34import android.os.SystemClock;
35import android.os.SystemProperties;
Doug Zongker43866e02010-01-07 12:09:54 -080036import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.util.EventLog;
Joe Onorato8a9b2202010-02-26 18:56:32 -080038import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039
40/**
Doug Zongker43866e02010-01-07 12:09:54 -080041 * This class implements a service to monitor the amount of disk
42 * storage space on the device. If the free storage on device is less
43 * than a tunable threshold value (a secure settings parameter;
44 * default 10%) a low memory notification is displayed to alert the
45 * user. If the user clicks on the low memory notification the
46 * Application Manager application gets launched to let the user free
47 * storage space.
48 *
49 * Event log events: A low memory event with the free storage on
50 * device in bytes is logged to the event log when the device goes low
51 * on storage space. The amount of free storage on the device is
52 * periodically logged to the event log. The log interval is a secure
53 * settings parameter with a default value of 12 hours. When the free
54 * storage differential goes below a threshold (again a secure
55 * settings parameter with a default value of 2MB), the free memory is
56 * logged to the event log.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057 */
Kenny Rootcf0b38c2011-03-22 14:17:59 -070058public class DeviceStorageMonitorService extends Binder {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059 private static final String TAG = "DeviceStorageMonitorService";
60 private static final boolean DEBUG = false;
Joe Onorato43a17652011-04-06 19:22:23 -070061 private static final boolean localLOGV = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 private static final int DEVICE_MEMORY_WHAT = 1;
63 private static final int MONITOR_INTERVAL = 1; //in minutes
64 private static final int LOW_MEMORY_NOTIFICATION_ID = 1;
65 private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10;
Dianne Hackborn247fe742011-01-08 17:25:57 -080066 private static final int DEFAULT_THRESHOLD_MAX_BYTES = 500*1024*1024; // 500MB
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 private static final int DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES = 12*60; //in minutes
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 private static final long DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD = 2 * 1024 * 1024; // 2MB
69 private static final long DEFAULT_CHECK_INTERVAL = MONITOR_INTERVAL*60*1000;
Jake Hambybb371632010-08-23 18:16:48 -070070 private static final int DEFAULT_FULL_THRESHOLD_BYTES = 1024*1024; // 1MB
Doug Zongker3161795b2009-10-07 15:14:03 -070071 private long mFreeMem; // on /data
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 private long mLastReportedFreeMem;
73 private long mLastReportedFreeMemTime;
74 private boolean mLowMemFlag=false;
Jake Hambybb371632010-08-23 18:16:48 -070075 private boolean mMemFullFlag=false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 private Context mContext;
77 private ContentResolver mContentResolver;
Doug Zongker3161795b2009-10-07 15:14:03 -070078 private long mTotalMemory; // on /data
79 private StatFs mDataFileStats;
80 private StatFs mSystemFileStats;
81 private StatFs mCacheFileStats;
82 private static final String DATA_PATH = "/data";
83 private static final String SYSTEM_PATH = "/system";
84 private static final String CACHE_PATH = "/cache";
85 private long mThreadStartTime = -1;
86 private boolean mClearSucceeded = false;
87 private boolean mClearingCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 private Intent mStorageLowIntent;
89 private Intent mStorageOkIntent;
Jake Hambybb371632010-08-23 18:16:48 -070090 private Intent mStorageFullIntent;
91 private Intent mStorageNotFullIntent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 private CachePackageDataObserver mClearCacheObserver;
93 private static final int _TRUE = 1;
94 private static final int _FALSE = 0;
Jake Hambybb371632010-08-23 18:16:48 -070095 private long mMemLowThreshold;
96 private int mMemFullThreshold;
Doug Zongker3161795b2009-10-07 15:14:03 -070097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 /**
99 * This string is used for ServiceManager access to this class.
100 */
Kenny Rootcf0b38c2011-03-22 14:17:59 -0700101 public static final String SERVICE = "devicestoragemonitor";
Doug Zongker3161795b2009-10-07 15:14:03 -0700102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 /**
Doug Zongker3161795b2009-10-07 15:14:03 -0700104 * Handler that checks the amount of disk space on the device and sends a
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 * notification if the device runs low on disk space
106 */
107 Handler mHandler = new Handler() {
108 @Override
109 public void handleMessage(Message msg) {
Jake Hambybb371632010-08-23 18:16:48 -0700110 //don't handle an invalid message
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 if (msg.what != DEVICE_MEMORY_WHAT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800112 Slog.e(TAG, "Will not process invalid message");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 return;
114 }
115 checkMemory(msg.arg1 == _TRUE);
116 }
117 };
Doug Zongker3161795b2009-10-07 15:14:03 -0700118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 class CachePackageDataObserver extends IPackageDataObserver.Stub {
120 public void onRemoveCompleted(String packageName, boolean succeeded) {
121 mClearSucceeded = succeeded;
122 mClearingCache = false;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800123 if(localLOGV) Slog.i(TAG, " Clear succeeded:"+mClearSucceeded
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 +", mClearingCache:"+mClearingCache+" Forcing memory check");
125 postCheckMemoryMsg(false, 0);
Doug Zongker3161795b2009-10-07 15:14:03 -0700126 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 }
Doug Zongker3161795b2009-10-07 15:14:03 -0700128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 private final void restatDataDir() {
Doug Zongker3161795b2009-10-07 15:14:03 -0700130 try {
131 mDataFileStats.restat(DATA_PATH);
132 mFreeMem = (long) mDataFileStats.getAvailableBlocks() *
133 mDataFileStats.getBlockSize();
134 } catch (IllegalArgumentException e) {
135 // use the old value of mFreeMem
136 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 // Allow freemem to be overridden by debug.freemem for testing
138 String debugFreeMem = SystemProperties.get("debug.freemem");
139 if (!"".equals(debugFreeMem)) {
140 mFreeMem = Long.parseLong(debugFreeMem);
141 }
Doug Zongker43866e02010-01-07 12:09:54 -0800142 // Read the log interval from secure settings
143 long freeMemLogInterval = Settings.Secure.getLong(mContentResolver,
144 Settings.Secure.SYS_FREE_STORAGE_LOG_INTERVAL,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES)*60*1000;
146 //log the amount of free memory in event log
147 long currTime = SystemClock.elapsedRealtime();
Doug Zongker3161795b2009-10-07 15:14:03 -0700148 if((mLastReportedFreeMemTime == 0) ||
149 (currTime-mLastReportedFreeMemTime) >= freeMemLogInterval) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 mLastReportedFreeMemTime = currTime;
Doug Zongker3161795b2009-10-07 15:14:03 -0700151 long mFreeSystem = -1, mFreeCache = -1;
152 try {
153 mSystemFileStats.restat(SYSTEM_PATH);
154 mFreeSystem = (long) mSystemFileStats.getAvailableBlocks() *
155 mSystemFileStats.getBlockSize();
156 } catch (IllegalArgumentException e) {
157 // ignore; report -1
158 }
159 try {
160 mCacheFileStats.restat(CACHE_PATH);
161 mFreeCache = (long) mCacheFileStats.getAvailableBlocks() *
162 mCacheFileStats.getBlockSize();
163 } catch (IllegalArgumentException e) {
164 // ignore; report -1
165 }
166 mCacheFileStats.restat(CACHE_PATH);
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800167 EventLog.writeEvent(EventLogTags.FREE_STORAGE_LEFT,
Doug Zongker3161795b2009-10-07 15:14:03 -0700168 mFreeMem, mFreeSystem, mFreeCache);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 }
Doug Zongker43866e02010-01-07 12:09:54 -0800170 // Read the reporting threshold from secure settings
171 long threshold = Settings.Secure.getLong(mContentResolver,
172 Settings.Secure.DISK_FREE_CHANGE_REPORTING_THRESHOLD,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD);
174 // If mFree changed significantly log the new value
175 long delta = mFreeMem - mLastReportedFreeMem;
176 if (delta > threshold || delta < -threshold) {
177 mLastReportedFreeMem = mFreeMem;
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800178 EventLog.writeEvent(EventLogTags.FREE_STORAGE_CHANGED, mFreeMem);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 }
180 }
Doug Zongker3161795b2009-10-07 15:14:03 -0700181
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 private final void clearCache() {
183 if (mClearCacheObserver == null) {
184 // Lazy instantiation
185 mClearCacheObserver = new CachePackageDataObserver();
186 }
187 mClearingCache = true;
188 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800189 if (localLOGV) Slog.i(TAG, "Clearing cache");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 IPackageManager.Stub.asInterface(ServiceManager.getService("package")).
Jake Hambybb371632010-08-23 18:16:48 -0700191 freeStorageAndNotify(mMemLowThreshold, mClearCacheObserver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800193 Slog.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 mClearingCache = false;
195 mClearSucceeded = false;
196 }
197 }
Doug Zongker3161795b2009-10-07 15:14:03 -0700198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 private final void checkMemory(boolean checkCache) {
Doug Zongker3161795b2009-10-07 15:14:03 -0700200 //if the thread that was started to clear cache is still running do nothing till its
201 //finished clearing cache. Ideally this flag could be modified by clearCache
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 // and should be accessed via a lock but even if it does this test will fail now and
203 //hopefully the next time this flag will be set to the correct value.
204 if(mClearingCache) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800205 if(localLOGV) Slog.i(TAG, "Thread already running just skip");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 //make sure the thread is not hung for too long
207 long diffTime = System.currentTimeMillis() - mThreadStartTime;
208 if(diffTime > (10*60*1000)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800209 Slog.w(TAG, "Thread that clears cache file seems to run for ever");
Doug Zongker3161795b2009-10-07 15:14:03 -0700210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 } else {
212 restatDataDir();
Joe Onorato8a9b2202010-02-26 18:56:32 -0800213 if (localLOGV) Slog.v(TAG, "freeMemory="+mFreeMem);
Doug Zongker3161795b2009-10-07 15:14:03 -0700214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 //post intent to NotificationManager to display icon if necessary
Jake Hambybb371632010-08-23 18:16:48 -0700216 if (mFreeMem < mMemLowThreshold) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 if (!mLowMemFlag) {
218 if (checkCache) {
219 // See if clearing cache helps
220 // Note that clearing cache is asynchronous and so we do a
221 // memory check again once the cache has been cleared.
222 mThreadStartTime = System.currentTimeMillis();
223 mClearSucceeded = false;
224 clearCache();
225 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800226 Slog.i(TAG, "Running low on memory. Sending notification");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 sendNotification();
228 mLowMemFlag = true;
229 }
230 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800231 if (localLOGV) Slog.v(TAG, "Running low on memory " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232 "notification already sent. do nothing");
233 }
234 } else {
235 if (mLowMemFlag) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800236 Slog.i(TAG, "Memory available. Cancelling notification");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 cancelNotification();
238 mLowMemFlag = false;
239 }
240 }
Jake Hambybb371632010-08-23 18:16:48 -0700241 if (mFreeMem < mMemFullThreshold) {
242 if (!mMemFullFlag) {
243 sendFullNotification();
244 mMemFullFlag = true;
245 }
246 } else {
247 if (mMemFullFlag) {
248 cancelFullNotification();
249 mMemFullFlag = false;
250 }
251 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 }
Joe Onorato8a9b2202010-02-26 18:56:32 -0800253 if(localLOGV) Slog.i(TAG, "Posting Message again");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 //keep posting messages to itself periodically
255 postCheckMemoryMsg(true, DEFAULT_CHECK_INTERVAL);
256 }
Doug Zongker3161795b2009-10-07 15:14:03 -0700257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 private void postCheckMemoryMsg(boolean clearCache, long delay) {
259 // Remove queued messages
260 mHandler.removeMessages(DEVICE_MEMORY_WHAT);
261 mHandler.sendMessageDelayed(mHandler.obtainMessage(DEVICE_MEMORY_WHAT,
262 clearCache ?_TRUE : _FALSE, 0),
263 delay);
264 }
Doug Zongker3161795b2009-10-07 15:14:03 -0700265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 /*
Doug Zongker3161795b2009-10-07 15:14:03 -0700267 * just query settings to retrieve the memory threshold.
Doug Zongker43866e02010-01-07 12:09:54 -0800268 * Preferred this over using a ContentObserver since Settings.Secure caches the value
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 * any way
270 */
271 private long getMemThreshold() {
Dianne Hackborn247fe742011-01-08 17:25:57 -0800272 long value = Settings.Secure.getInt(
Doug Zongker3161795b2009-10-07 15:14:03 -0700273 mContentResolver,
Doug Zongker43866e02010-01-07 12:09:54 -0800274 Settings.Secure.SYS_STORAGE_THRESHOLD_PERCENTAGE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 DEFAULT_THRESHOLD_PERCENTAGE);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800276 if(localLOGV) Slog.v(TAG, "Threshold Percentage="+value);
Dianne Hackborn247fe742011-01-08 17:25:57 -0800277 value *= mTotalMemory;
278 long maxValue = Settings.Secure.getInt(
279 mContentResolver,
280 Settings.Secure.SYS_STORAGE_THRESHOLD_MAX_BYTES,
281 DEFAULT_THRESHOLD_MAX_BYTES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282 //evaluate threshold value
Dianne Hackborn247fe742011-01-08 17:25:57 -0800283 return value < maxValue ? value : maxValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 }
285
Jake Hambybb371632010-08-23 18:16:48 -0700286 /*
287 * just query settings to retrieve the memory full threshold.
288 * Preferred this over using a ContentObserver since Settings.Secure caches the value
289 * any way
290 */
291 private int getMemFullThreshold() {
292 int value = Settings.Secure.getInt(
293 mContentResolver,
294 Settings.Secure.SYS_STORAGE_FULL_THRESHOLD_BYTES,
295 DEFAULT_FULL_THRESHOLD_BYTES);
296 if(localLOGV) Slog.v(TAG, "Full Threshold Bytes="+value);
297 return value;
298 }
299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 /**
301 * Constructor to run service. initializes the disk space threshold value
302 * and posts an empty message to kickstart the process.
303 */
304 public DeviceStorageMonitorService(Context context) {
305 mLastReportedFreeMemTime = 0;
306 mContext = context;
307 mContentResolver = mContext.getContentResolver();
308 //create StatFs object
Doug Zongker3161795b2009-10-07 15:14:03 -0700309 mDataFileStats = new StatFs(DATA_PATH);
310 mSystemFileStats = new StatFs(SYSTEM_PATH);
311 mCacheFileStats = new StatFs(CACHE_PATH);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 //initialize total storage on device
Doug Zongker3161795b2009-10-07 15:14:03 -0700313 mTotalMemory = ((long)mDataFileStats.getBlockCount() *
314 mDataFileStats.getBlockSize())/100L;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 mStorageLowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_LOW);
Jeff Hamilton4b330922010-06-04 15:16:06 -0500316 mStorageLowIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK);
Jeff Hamilton4b330922010-06-04 15:16:06 -0500318 mStorageOkIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
Jake Hambybb371632010-08-23 18:16:48 -0700319 mStorageFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_FULL);
320 mStorageFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
321 mStorageNotFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL);
322 mStorageNotFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
323 // cache storage thresholds
324 mMemLowThreshold = getMemThreshold();
325 mMemFullThreshold = getMemFullThreshold();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 checkMemory(true);
327 }
Doug Zongker3161795b2009-10-07 15:14:03 -0700328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329
330 /**
331 * This method sends a notification to NotificationManager to display
332 * an error dialog indicating low disk space and launch the Installer
333 * application
334 */
335 private final void sendNotification() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800336 if(localLOGV) Slog.i(TAG, "Sending low memory notification");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 //log the event to event log with the amount of free storage(in bytes) left on the device
Doug Zongkerab5c49c2009-12-04 10:31:43 -0800338 EventLog.writeEvent(EventLogTags.LOW_STORAGE, mFreeMem);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 // Pack up the values and broadcast them to everyone
340 Intent lowMemIntent = new Intent(Intent.ACTION_MANAGE_PACKAGE_STORAGE);
341 lowMemIntent.putExtra("memory", mFreeMem);
342 lowMemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Doug Zongker3161795b2009-10-07 15:14:03 -0700343 NotificationManager mNotificationMgr =
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 (NotificationManager)mContext.getSystemService(
345 Context.NOTIFICATION_SERVICE);
346 CharSequence title = mContext.getText(
347 com.android.internal.R.string.low_internal_storage_view_title);
348 CharSequence details = mContext.getText(
349 com.android.internal.R.string.low_internal_storage_view_text);
350 PendingIntent intent = PendingIntent.getActivity(mContext, 0, lowMemIntent, 0);
351 Notification notification = new Notification();
352 notification.icon = com.android.internal.R.drawable.stat_notify_disk_full;
353 notification.tickerText = title;
354 notification.flags |= Notification.FLAG_NO_CLEAR;
355 notification.setLatestEventInfo(mContext, title, details, intent);
356 mNotificationMgr.notify(LOW_MEMORY_NOTIFICATION_ID, notification);
357 mContext.sendStickyBroadcast(mStorageLowIntent);
358 }
359
360 /**
361 * Cancels low storage notification and sends OK intent.
362 */
363 private final void cancelNotification() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800364 if(localLOGV) Slog.i(TAG, "Canceling low memory notification");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 NotificationManager mNotificationMgr =
366 (NotificationManager)mContext.getSystemService(
367 Context.NOTIFICATION_SERVICE);
368 //cancel notification since memory has been freed
369 mNotificationMgr.cancel(LOW_MEMORY_NOTIFICATION_ID);
370
371 mContext.removeStickyBroadcast(mStorageLowIntent);
372 mContext.sendBroadcast(mStorageOkIntent);
373 }
Doug Zongker3161795b2009-10-07 15:14:03 -0700374
Jake Hambybb371632010-08-23 18:16:48 -0700375 /**
376 * Send a notification when storage is full.
377 */
378 private final void sendFullNotification() {
379 if(localLOGV) Slog.i(TAG, "Sending memory full notification");
380 mContext.sendStickyBroadcast(mStorageFullIntent);
381 }
382
383 /**
384 * Cancels memory full notification and sends "not full" intent.
385 */
386 private final void cancelFullNotification() {
387 if(localLOGV) Slog.i(TAG, "Canceling memory full notification");
388 mContext.removeStickyBroadcast(mStorageFullIntent);
389 mContext.sendBroadcast(mStorageNotFullIntent);
390 }
391
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 public void updateMemory() {
393 int callingUid = getCallingUid();
394 if(callingUid != Process.SYSTEM_UID) {
395 return;
396 }
397 // force an early check
398 postCheckMemoryMsg(true, 0);
399 }
Kenny Root62e1b4e2011-03-14 17:13:39 -0700400
401 /**
402 * Callable from other things in the system service to obtain the low memory
403 * threshold.
404 *
405 * @return low memory threshold in bytes
406 */
407 public long getMemoryLowThreshold() {
408 return mMemLowThreshold;
409 }
410
411 /**
412 * Callable from other things in the system process to check whether memory
413 * is low.
414 *
415 * @return true is memory is low
416 */
417 public boolean isMemoryLow() {
418 return mLowMemFlag;
419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420}