diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/app/ActivityManager.java | 33 | ||||
-rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 25 | ||||
-rw-r--r-- | core/java/android/app/IActivityManager.java | 10 | ||||
-rw-r--r-- | core/java/android/content/ComponentCallbacks2.java | 38 | ||||
-rw-r--r-- | core/java/android/view/HardwareRenderer.java | 13 | ||||
-rw-r--r-- | core/java/android/view/WindowManagerImpl.java | 36 |
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); } } |