Add API to retrieve memory used by running processes.

Change-Id: I9c1935c2ef3c78bd67ec4dfd811a1caaab4514c3
diff --git a/api/current.xml b/api/current.xml
index 2c9a087..e64726a 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -17563,6 +17563,19 @@
 <parameter name="outInfo" type="android.app.ActivityManager.MemoryInfo">
 </parameter>
 </method>
+<method name="getProcessMemoryInfo"
+ return="android.os.Debug.MemoryInfo[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="pids" type="int[]">
+</parameter>
+</method>
 <method name="getProcessesInErrorState"
  return="java.util.List&lt;android.app.ActivityManager.ProcessErrorStateInfo&gt;"
  abstract="false"
@@ -101301,6 +101314,39 @@
  visibility="public"
 >
 </method>
+<method name="getTotalPrivateDirty"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalPss"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalSharedDirty"
+ 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"
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index e96de07..be89ee6 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -22,6 +22,7 @@
 import android.content.pm.ConfigurationInfo;
 import android.content.pm.IPackageDataObserver;
 import android.graphics.Bitmap;
+import android.os.Debug;
 import android.os.RemoteException;
 import android.os.Handler;
 import android.os.Parcel;
@@ -854,6 +855,22 @@
     }
     
     /**
+     * Return information about the memory usage of one or more processes.
+     * 
+     * @param pids The pids of the processes whose memory usage is to be
+     * retrieved.
+     * @return Returns an array of memory information, one for each
+     * requested pid.
+     */
+    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
+        try {
+            return ActivityManagerNative.getDefault().getProcessMemoryInfo(pids);
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+    
+    /**
      * Have the system perform a force stop of everything associated with
      * the given application package.  All processes that share its uid
      * will be killed, all services it has running stopped, all activities
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 4796e49..722c75c 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1137,11 +1137,10 @@
         
         case GET_PROCESS_MEMORY_INFO_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
-            int pid = data.readInt();
-            Debug.MemoryInfo mi = new Debug.MemoryInfo();
-            getProcessMemoryInfo(pid, mi);
+            int[] pids = data.createIntArray();
+            Debug.MemoryInfo[] res =  getProcessMemoryInfo(pids);
             reply.writeNoException();
-            mi.writeToParcel(reply, 0);
+            reply.writeTypedArray(res, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
             return true;
         }
 
@@ -2504,17 +2503,18 @@
         reply.recycle();
     }
     
-    public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo)
+    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
-        data.writeInt(pid);
+        data.writeIntArray(pids);
         mRemote.transact(GET_PROCESS_MEMORY_INFO_TRANSACTION, data, reply, 0);
         reply.readException();
-        outInfo.readFromParcel(reply);
+        Debug.MemoryInfo[] res = reply.createTypedArray(Debug.MemoryInfo.CREATOR);
         data.recycle();
         reply.recycle();
+        return res;
     }
 
     public void killApplicationProcess(String processName, int uid) throws RemoteException {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 8244645..7d9dd3a 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -281,7 +281,7 @@
     
     public void closeSystemDialogs(String reason) throws RemoteException;
     
-    public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo)
+    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
             throws RemoteException;
     
     /*
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 5352cf6..b4f64b6 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -129,6 +129,27 @@
         public MemoryInfo() {
         }
 
+        /**
+         * Return total PSS memory usage in kB.
+         */
+        public int getTotalPss() {
+            return dalvikPss + nativePss + otherPss;
+        }
+        
+        /**
+         * Return total private dirty memory usage in kB.
+         */
+        public int getTotalPrivateDirty() {
+            return dalvikPrivateDirty + nativePrivateDirty + otherPrivateDirty;
+        }
+        
+        /**
+         * Return total shared dirty memory usage in kB.
+         */
+        public int getTotalSharedDirty() {
+            return dalvikSharedDirty + nativeSharedDirty + otherSharedDirty;
+        }
+        
         public int describeContents() {
             return 0;
         }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 66ef557..1597270 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -4921,23 +4921,14 @@
         Binder.restoreCallingIdentity(origId);
     }
     
-    public void getProcessMemoryInfo(int pid, Debug.MemoryInfo mi)
+    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
             throws RemoteException {
-        ProcessRecord proc;
-        synchronized (mPidsSelfLocked) {
-            proc = mPidsSelfLocked.get(pid);
+        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
+        for (int i=pids.length-1; i>=0; i--) {
+            infos[i] = new Debug.MemoryInfo();
+            Debug.getMemoryInfo(pids[i], infos[i]);
         }
-        
-        if (proc == null) {
-            throw new RemoteException();
-        }
-        
-        IApplicationThread thread = proc.thread;
-        if (thread == null) {
-            throw new RemoteException();
-        }
-        
-        thread.getMemoryInfo(mi);
+        return infos;
     }
 
     public void killApplicationProcess(String processName, int uid) {