Merge "Work on more low memory reporting to apps."

This commit is contained in:
Dianne Hackborn
2012-03-06 19:06:25 -08:00
committed by Android (Google) Code Review
8 changed files with 181 additions and 63 deletions

View File

@@ -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.
*

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -51,16 +51,50 @@ 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);
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}