diff options
-rw-r--r-- | api/current.xml | 115 | ||||
-rw-r--r-- | core/java/android/app/ActivityManager.java | 40 | ||||
-rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 26 | ||||
-rw-r--r-- | core/java/android/app/ActivityThread.java | 4 | ||||
-rw-r--r-- | core/java/android/app/ApplicationThreadNative.java | 22 | ||||
-rw-r--r-- | core/java/android/app/IActivityManager.java | 5 | ||||
-rw-r--r-- | core/java/android/app/IApplicationThread.java | 3 | ||||
-rw-r--r-- | core/java/android/os/Debug.java | 53 | ||||
-rw-r--r-- | core/jni/android_os_Debug.cpp | 12 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 33 |
10 files changed, 308 insertions, 5 deletions
diff --git a/api/current.xml b/api/current.xml index 7e6c2df..46dfd89 100644 --- a/api/current.xml +++ b/api/current.xml @@ -18039,6 +18039,50 @@ visibility="public" > </field> +<field name="FLAG_FOREGROUND" + type="int" + transient="false" + volatile="false" + value="2" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="FLAG_PERSISTENT_PROCESS" + type="int" + transient="false" + volatile="false" + value="8" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="FLAG_STARTED" + type="int" + transient="false" + volatile="false" + value="1" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="FLAG_SYSTEM_PROCESS" + type="int" + transient="false" + volatile="false" + value="4" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="activeSince" type="long" transient="false" @@ -18069,6 +18113,16 @@ visibility="public" > </field> +<field name="flags" + type="int" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="foreground" type="boolean" transient="false" @@ -18139,6 +18193,16 @@ visibility="public" > </field> +<field name="uid" + type="int" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> </class> <class name="ActivityManager.RunningTaskInfo" extends="java.lang.Object" @@ -97544,6 +97608,8 @@ deprecated="not deprecated" visibility="public" > +<implements name="android.os.Parcelable"> +</implements> <constructor name="Debug.MemoryInfo" type="android.os.Debug.MemoryInfo" static="false" @@ -97552,6 +97618,55 @@ visibility="public" > </constructor> +<method name="describeContents" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="readFromParcel" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="source" type="android.os.Parcel"> +</parameter> +</method> +<method name="writeToParcel" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="dest" type="android.os.Parcel"> +</parameter> +<parameter name="flags" type="int"> +</parameter> +</method> +<field name="CREATOR" + type="android.os.Parcelable.Creator" + transient="false" + volatile="false" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="dalvikPrivateDirty" type="int" transient="false" diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 07520c9d..ad06fa9 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -289,6 +289,11 @@ public class ActivityManager { public int pid; /** + * The UID that owns this service. + */ + public int uid; + + /** * The name of the process this service runs in. */ public String process; @@ -299,7 +304,7 @@ public class ActivityManager { public boolean foreground; /** - * The time when the service was first made activity, either by someone + * The time when the service was first made active, either by someone * starting or binding to it. */ public long activeSince; @@ -332,6 +337,35 @@ public class ActivityManager { */ public long restarting; + /** + * Bit for {@link #flags}: set if this service has been + * explicitly started. + */ + public static final int FLAG_STARTED = 1<<0; + + /** + * Bit for {@link #flags}: set if the service has asked to + * run as a foreground process. + */ + public static final int FLAG_FOREGROUND = 1<<1; + + /** + * Bit for {@link #flags): set if the service is running in a + * core system process. + */ + public static final int FLAG_SYSTEM_PROCESS = 1<<2; + + /** + * Bit for {@link #flags): set if the service is running in a + * persistent process. + */ + public static final int FLAG_PERSISTENT_PROCESS = 1<<3; + + /** + * Running flags. + */ + public int flags; + public RunningServiceInfo() { } @@ -342,6 +376,7 @@ public class ActivityManager { public void writeToParcel(Parcel dest, int flags) { ComponentName.writeToParcel(service, dest); dest.writeInt(pid); + dest.writeInt(uid); dest.writeString(process); dest.writeInt(foreground ? 1 : 0); dest.writeLong(activeSince); @@ -350,11 +385,13 @@ public class ActivityManager { dest.writeInt(crashCount); dest.writeLong(lastActivityTime); dest.writeLong(restarting); + dest.writeInt(this.flags); } public void readFromParcel(Parcel source) { service = ComponentName.readFromParcel(source); pid = source.readInt(); + uid = source.readInt(); process = source.readString(); foreground = source.readInt() != 0; activeSince = source.readLong(); @@ -363,6 +400,7 @@ public class ActivityManager { crashCount = source.readInt(); lastActivityTime = source.readLong(); restarting = source.readLong(); + flags = source.readInt(); } public static final Creator<RunningServiceInfo> CREATOR = new Creator<RunningServiceInfo>() { diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index d14ec15..1bb21b9 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -29,6 +29,7 @@ import android.graphics.Bitmap; import android.net.Uri; import android.os.Binder; import android.os.Bundle; +import android.os.Debug; import android.os.Parcelable; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -1107,6 +1108,16 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } + + case GET_PROCESS_MEMORY_INFO_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + int pid = data.readInt(); + Debug.MemoryInfo mi = new Debug.MemoryInfo(); + getProcessMemoryInfo(pid, mi); + reply.writeNoException(); + mi.writeToParcel(reply, 0); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -2424,6 +2435,19 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } - + + public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo) + throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeInt(pid); + mRemote.transact(GET_PROCESS_MEMORY_INFO_TRANSACTION, data, reply, 0); + reply.readException(); + outInfo.readFromParcel(reply); + data.recycle(); + reply.recycle(); + } + private IBinder mRemote; } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 1e915b4..b4e57e0 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1546,6 +1546,10 @@ public final class ActivityThread { } } + public void getMemoryInfo(Debug.MemoryInfo outInfo) { + Debug.getMemoryInfo(outInfo); + } + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { long nativeMax = Debug.getNativeHeapSize() / 1024; diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index ad64465..15bf9ed 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -26,6 +26,7 @@ import android.content.pm.ServiceInfo; import android.content.res.Configuration; import android.os.Binder; import android.os.Bundle; +import android.os.Debug; import android.os.Parcelable; import android.os.RemoteException; import android.os.IBinder; @@ -370,6 +371,16 @@ public abstract class ApplicationThreadNative extends Binder scheduleDestroyBackupAgent(appInfo); return true; } + + case GET_MEMORY_INFO_TRANSACTION: + { + data.enforceInterface(IApplicationThread.descriptor); + Debug.MemoryInfo mi = new Debug.MemoryInfo(); + getMemoryInfo(mi); + reply.writeNoException(); + mi.writeToParcel(reply, 0); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -756,5 +767,16 @@ class ApplicationThreadProxy implements IApplicationThread { IBinder.FLAG_ONEWAY); data.recycle(); } + + public void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IApplicationThread.descriptor); + mRemote.transact(GET_MEMORY_INFO_TRANSACTION, data, reply, 0); + reply.readException(); + outInfo.readFromParcel(reply); + data.recycle(); + reply.recycle(); + } } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index c3e7224..64daea9 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -30,6 +30,7 @@ import android.content.pm.ProviderInfo; import android.content.res.Configuration; import android.graphics.Bitmap; import android.net.Uri; +import android.os.Debug; import android.os.RemoteException; import android.os.IBinder; import android.os.IInterface; @@ -272,6 +273,9 @@ public interface IActivityManager extends IInterface { public void closeSystemDialogs(String reason) throws RemoteException; + public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo) + throws RemoteException; + /* * Private non-Binder interfaces */ @@ -428,4 +432,5 @@ public interface IActivityManager extends IInterface { int START_ACTIVITY_IN_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94; int KILL_APPLICATION_WITH_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95; int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96; + int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97; } diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java index 6faaa34..da9a957 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -25,6 +25,7 @@ import android.content.pm.ProviderInfo; import android.content.pm.ServiceInfo; import android.content.res.Configuration; import android.os.Bundle; +import android.os.Debug; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.IBinder; @@ -97,6 +98,7 @@ public interface IApplicationThread extends IInterface { void profilerControl(boolean start, String path, ParcelFileDescriptor fd) throws RemoteException; void setSchedulingGroup(int group) throws RemoteException; + void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException; String descriptor = "android.app.IApplicationThread"; @@ -130,4 +132,5 @@ public interface IApplicationThread extends IInterface { int SET_SCHEDULING_GROUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28; int SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29; int SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30; + int GET_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31; } diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index b0fc78e..5352cf6 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -104,7 +104,7 @@ public final class Debug * This class is used to retrieved various statistics about the memory mappings for this * process. The returns info broken down by dalvik, native, and other. All results are in kB. */ - public static class MemoryInfo { + public static class MemoryInfo implements Parcelable { /** The proportional set size for dalvik. */ public int dalvikPss; /** The private dirty pages used by dalvik. */ @@ -125,6 +125,50 @@ public final class Debug public int otherPrivateDirty; /** The shared dirty pages used by everything else. */ public int otherSharedDirty; + + public MemoryInfo() { + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(dalvikPss); + dest.writeInt(dalvikPrivateDirty); + dest.writeInt(dalvikSharedDirty); + dest.writeInt(nativePss); + dest.writeInt(nativePrivateDirty); + dest.writeInt(nativeSharedDirty); + dest.writeInt(otherPss); + dest.writeInt(otherPrivateDirty); + dest.writeInt(otherSharedDirty); + } + + public void readFromParcel(Parcel source) { + dalvikPss = source.readInt(); + dalvikPrivateDirty = source.readInt(); + dalvikSharedDirty = source.readInt(); + nativePss = source.readInt(); + nativePrivateDirty = source.readInt(); + nativeSharedDirty = source.readInt(); + otherPss = source.readInt(); + otherPrivateDirty = source.readInt(); + otherSharedDirty = source.readInt(); + } + + public static final Creator<MemoryInfo> CREATOR = new Creator<MemoryInfo>() { + public MemoryInfo createFromParcel(Parcel source) { + return new MemoryInfo(source); + } + public MemoryInfo[] newArray(int size) { + return new MemoryInfo[size]; + } + }; + + private MemoryInfo(Parcel source) { + readFromParcel(source); + } } @@ -556,6 +600,13 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo public static native void getMemoryInfo(MemoryInfo memoryInfo); /** + * Note: currently only works when the requested pid has the same UID + * as the caller. + * @hide + */ + public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo); + + /** * Establish an object allocation limit in the current thread. Useful * for catching regressions in code that is expected to operate * without causing any allocations. diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index b4c60f1..3ee404a 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -200,12 +200,13 @@ static void load_maps(int pid, stats_t* stats) fclose(fp); } -static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object) +static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, + jint pid, jobject object) { stats_t stats; memset(&stats, 0, sizeof(stats_t)); - load_maps(getpid(), &stats); + load_maps(pid, &stats); env->SetIntField(object, dalvikPss_field, stats.dalvikPss); env->SetIntField(object, dalvikPrivateDirty_field, stats.dalvikPrivateDirty); @@ -220,6 +221,11 @@ static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject o env->SetIntField(object, otherSharedDirty_field, stats.otherSharedDirty); } +static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object) +{ + android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object); +} + static jint read_binder_stat(const char* stat) { FILE* fp = fopen(BINDER_STATS, "r"); @@ -281,6 +287,8 @@ static JNINativeMethod gMethods[] = { (void*) android_os_Debug_getNativeHeapFreeSize }, { "getMemoryInfo", "(Landroid/os/Debug$MemoryInfo;)V", (void*) android_os_Debug_getDirtyPages }, + { "getMemoryInfo", "(ILandroid/os/Debug$MemoryInfo;)V", + (void*) android_os_Debug_getDirtyPagesPid }, { "getBinderSentTransactions", "()I", (void*) android_os_Debug_getBinderSentTransactions }, { "getBinderReceivedTransactions", "()I", diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index d4e69c0..867d8a6 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -68,6 +68,7 @@ import android.graphics.Bitmap; import android.net.Uri; import android.os.Binder; import android.os.Bundle; +import android.os.Debug; import android.os.Environment; import android.os.FileUtils; import android.os.Handler; @@ -4895,6 +4896,25 @@ public final class ActivityManagerService extends ActivityManagerNative implemen Binder.restoreCallingIdentity(origId); } + public void getProcessMemoryInfo(int pid, Debug.MemoryInfo mi) + throws RemoteException { + ProcessRecord proc; + synchronized (mPidsSelfLocked) { + proc = mPidsSelfLocked.get(pid); + } + + if (proc == null) { + throw new RemoteException(); + } + + IApplicationThread thread = proc.thread; + if (thread == null) { + throw new RemoteException(); + } + + thread.getMemoryInfo(mi); + } + private void restartPackageLocked(final String packageName, int uid) { uninstallPackageLocked(packageName, uid, false); Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, @@ -9818,6 +9838,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (r.app != null) { info.pid = r.app.pid; } + info.uid = r.appInfo.uid; info.process = r.processName; info.foreground = r.isForeground; info.activeSince = r.createTime; @@ -9825,6 +9846,18 @@ public final class ActivityManagerService extends ActivityManagerNative implemen info.clientCount = r.connections.size(); info.crashCount = r.crashCount; info.lastActivityTime = r.lastActivity; + if (r.isForeground) { + info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; + } + if (r.startRequested) { + info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; + } + if (r.app != null && r.app.pid == Process.myPid()) { + info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; + } + if (r.app != null && r.app.persistent) { + info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; + } return info; } |