summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2012-03-06 14:57:58 -0800
committerDianne Hackborn <hackbod@google.com>2012-03-06 18:46:32 -0800
commit27ff913d56de8400083a13fc572e2812b32c890c (patch)
treef30ec6efb44658b448c5e049bf0c1c3e40f0f06c /core
parent4f03d35f9c040222e6a46dde807fe2ff7852beb8 (diff)
downloadframeworks_base-27ff913d56de8400083a13fc572e2812b32c890c.zip
frameworks_base-27ff913d56de8400083a13fc572e2812b32c890c.tar.gz
frameworks_base-27ff913d56de8400083a13fc572e2812b32c890c.tar.bz2
Work on more low memory reporting to apps.
There are now some new trim memory levels that are sent to non-background applications as RAM becomes low. There is a new API for an application to retrieve information about memory trimming and such on demand. Fixed various checks against the memory trim level to be robust (not compare against exact values). Change-Id: Ifd1c6151124350168aef20a94e517166fd2e03eb
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/ActivityManager.java33
-rw-r--r--core/java/android/app/ActivityManagerNative.java25
-rw-r--r--core/java/android/app/IActivityManager.java10
-rw-r--r--core/java/android/content/ComponentCallbacks2.java38
-rw-r--r--core/java/android/view/HardwareRenderer.java13
-rw-r--r--core/java/android/view/WindowManagerImpl.java36
6 files changed, 117 insertions, 38 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d98d87b..59c803e 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1145,7 +1145,14 @@ public class ActivityManager {
* @hide
*/
public int flags;
-
+
+ /**
+ * Last memory trim level reported to the process: corresponds to
+ * the values supplied to {@link android.content.ComponentCallbacks2#onTrimMemory(int)
+ * ComponentCallbacks2.onTrimMemory(int)}.
+ */
+ public int lastTrimLevel;
+
/**
* Constant for {@link #importance}: this process is running the
* foreground UI.
@@ -1212,7 +1219,7 @@ public class ActivityManager {
* be maintained in the future.
*/
public int lru;
-
+
/**
* Constant for {@link #importanceReasonCode}: nothing special has
* been specified for the reason for this level.
@@ -1282,6 +1289,7 @@ public class ActivityManager {
dest.writeInt(uid);
dest.writeStringArray(pkgList);
dest.writeInt(this.flags);
+ dest.writeInt(lastTrimLevel);
dest.writeInt(importance);
dest.writeInt(lru);
dest.writeInt(importanceReasonCode);
@@ -1296,6 +1304,7 @@ public class ActivityManager {
uid = source.readInt();
pkgList = source.readStringArray();
flags = source.readInt();
+ lastTrimLevel = source.readInt();
importance = source.readInt();
lru = source.readInt();
importanceReasonCode = source.readInt();
@@ -1349,7 +1358,25 @@ public class ActivityManager {
return null;
}
}
-
+
+ /**
+ * Return global memory state information for the calling process. This
+ * does not fill in all fields of the {@link RunningAppProcessInfo}. The
+ * only fields that will be filled in are
+ * {@link RunningAppProcessInfo#pid},
+ * {@link RunningAppProcessInfo#uid},
+ * {@link RunningAppProcessInfo#lastTrimLevel},
+ * {@link RunningAppProcessInfo#importance},
+ * {@link RunningAppProcessInfo#lru}, and
+ * {@link RunningAppProcessInfo#importanceReasonCode}.
+ */
+ static public void getMyMemoryState(RunningAppProcessInfo outState) {
+ try {
+ ActivityManagerNative.getDefault().getMyMemoryState(outState);
+ } catch (RemoteException e) {
+ }
+ }
+
/**
* Return information about the memory usage of one or more processes.
*
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 24079a5..b952649 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1126,7 +1126,17 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeNoException();
return true;
}
-
+
+ case GET_MY_MEMORY_STATE_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ ActivityManager.RunningAppProcessInfo info =
+ new ActivityManager.RunningAppProcessInfo();
+ getMyMemoryState(info);
+ reply.writeNoException();
+ info.writeToParcel(reply, 0);
+ return true;
+ }
+
case GET_DEVICE_CONFIGURATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
ConfigurationInfo config = getDeviceConfigurationInfo();
@@ -2973,6 +2983,19 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle();
}
+ public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)
+ throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ mRemote.transact(GET_MY_MEMORY_STATE_TRANSACTION, data, reply, 0);
+ reply.readException();
+ outInfo.readFromParcel(reply);
+ reply.recycle();
+ data.recycle();
+ }
+
public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException
{
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 53a71db..ea2545f 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -278,13 +278,16 @@ public interface IActivityManager extends IInterface {
* SIGUSR1 is delivered. All others are ignored.
*/
public void signalPersistentProcesses(int signal) throws RemoteException;
- // Retrieve info of applications installed on external media that are currently
- // running.
+ // Retrieve running application processes in the system
public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses()
throws RemoteException;
- // Retrieve running application processes in the system
+ // Retrieve info of applications installed on external media that are currently
+ // running.
public List<ApplicationInfo> getRunningExternalApplications()
throws RemoteException;
+ // Get memory information about the calling process.
+ public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)
+ throws RemoteException;
// Get device configuration
public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException;
@@ -606,4 +609,5 @@ public interface IActivityManager extends IInterface {
int KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+139;
int GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+140;
int REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+141;
+ int GET_MY_MEMORY_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+142;
}
diff --git a/core/java/android/content/ComponentCallbacks2.java b/core/java/android/content/ComponentCallbacks2.java
index 8b9f97c..85294dd 100644
--- a/core/java/android/content/ComponentCallbacks2.java
+++ b/core/java/android/content/ComponentCallbacks2.java
@@ -52,15 +52,49 @@ public interface ComponentCallbacks2 extends ComponentCallbacks {
static final int TRIM_MEMORY_UI_HIDDEN = 20;
/**
+ * Level for {@link #onTrimMemory(int)}: the process is not an expendable
+ * background process, but the device is running extremely low on memory
+ * and is about to not be able to keep any background processes running.
+ * Your running process should free up as many non-critical resources as it
+ * can to allow that memory to be used elsewhere. The next thing that
+ * will happen after this is {@link #onLowMemory()} called to report that
+ * nothing at all can be kept in the background, a situation that can start
+ * to notably impact the user.
+ */
+ static final int TRIM_MEMORY_RUNNING_CRITICAL = 15;
+
+ /**
+ * Level for {@link #onTrimMemory(int)}: the process is not an expendable
+ * background process, but the device is running low on memory.
+ * Your running process should free up unneeded resources to allow that
+ * memory to be used elsewhere.
+ */
+ static final int TRIM_MEMORY_RUNNING_LOW = 10;
+
+
+ /**
+ * Level for {@link #onTrimMemory(int)}: the process is not an expendable
+ * background process, but the device is running moderately low on memory.
+ * Your running process may want to release some unneeded resources for
+ * use elsewhere.
+ */
+ static final int TRIM_MEMORY_RUNNING_MODERATE = 5;
+
+ /**
* Called when the operating system has determined that it is a good
* time for a process to trim unneeded memory from its process. This will
* happen for example when it goes in the background and there is not enough
- * memory to keep as many background processes running as desired.
+ * memory to keep as many background processes running as desired. You
+ * should never compare to exact values of the level, since new intermediate
+ * values may be added -- you will typically want to compare if the value
+ * is greater or equal to a level you are interested in.
*
* @param level The context of the trim, giving a hint of the amount of
* trimming the application may like to perform. May be
* {@link #TRIM_MEMORY_COMPLETE}, {@link #TRIM_MEMORY_MODERATE},
- * {@link #TRIM_MEMORY_BACKGROUND}, or {@link #TRIM_MEMORY_UI_HIDDEN}.
+ * {@link #TRIM_MEMORY_BACKGROUND}, {@link #TRIM_MEMORY_UI_HIDDEN},
+ * {@link #TRIM_MEMORY_RUNNING_CRITICAL}, {@link #TRIM_MEMORY_RUNNING_LOW},
+ * or {@link #TRIM_MEMORY_RUNNING_MODERATE}.
*/
void onTrimMemory(int level);
}
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index ec95863..bf91700 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -1284,15 +1284,10 @@ public abstract class HardwareRenderer {
usePbufferSurface(managedContext.getContext());
}
- switch (level) {
- case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
- case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
- case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
- GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
- break;
- case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
- GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
- break;
+ if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
+ GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
+ } else if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
+ GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
}
}
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index d482b35..0e4a30f 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -432,29 +432,25 @@ public class WindowManagerImpl implements WindowManager {
*/
public void trimMemory(int level) {
if (HardwareRenderer.isAvailable()) {
- switch (level) {
- case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
- case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
- // On low and medium end gfx devices
- if (!ActivityManager.isHighEndGfx(getDefaultDisplay())) {
- // Destroy all hardware surfaces and resources associated to
- // known windows
- synchronized (this) {
- if (mViews == null) return;
- int count = mViews.length;
- for (int i = 0; i < count; i++) {
- mRoots[i].terminateHardwareResources();
- }
+ // On low and medium end gfx devices
+ if (!ActivityManager.isHighEndGfx(getDefaultDisplay())) {
+ if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
+ // Destroy all hardware surfaces and resources associated to
+ // known windows
+ synchronized (this) {
+ if (mViews == null) return;
+ int count = mViews.length;
+ for (int i = 0; i < count; i++) {
+ mRoots[i].terminateHardwareResources();
}
- // Force a full memory flush
- HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
- mNeedsEglTerminate = true;
- break;
}
- // high end gfx devices fall through to next case
- default:
- HardwareRenderer.trimMemory(level);
+ // Force a full memory flush
+ HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
+ mNeedsEglTerminate = true;
+ return;
+ }
}
+ HardwareRenderer.trimMemory(level);
}
}