diff --git a/res/layout/running_services.xml b/res/layout/running_services.xml
index 8fe7f9f76d2..120a1135bed 100644
--- a/res/layout/running_services.xml
+++ b/res/layout/running_services.xml
@@ -15,16 +15,46 @@
* limitations under the License.
-->
-
-
-
+
+
+
+
+
-
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:background="?android:attr/colorForeground"
+ android:padding="4dp">
+
+
+
+
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index bb786c2bed6..8dadc54143e 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -50,10 +50,10 @@
- - Off
- - Some
- - All
- - Slow
+ - No animations
+ - Some animations
+ - All animations
+ - Slower all animations
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 847e879d70b..4d89630ceeb 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1422,9 +1422,13 @@ found in the list of installed applications.
Cancel
- Started by application
+ Started by application: select to stop
%1$s: select to manage
+
+ Background procs: %1$d
+
+ Foreground procs: %1$d
diff --git a/src/com/android/settings/RunningServices.java b/src/com/android/settings/RunningServices.java
index 675c59e5af2..5593ce95cd3 100644
--- a/src/com/android/settings/RunningServices.java
+++ b/src/com/android/settings/RunningServices.java
@@ -23,28 +23,17 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.PendingIntent;
-import android.app.ProgressDialog;
-import android.content.BroadcastReceiver;
+import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageStatsObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageStats;
import android.content.pm.ServiceInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Configuration;
import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.database.Cursor;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
@@ -54,24 +43,16 @@ import android.os.SystemClock;
import android.text.format.DateUtils;
import android.text.format.Formatter;
import android.util.AttributeSet;
-import android.util.Config;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.view.Window;
import android.widget.AbsListView;
-import android.widget.AdapterView;
import android.widget.BaseAdapter;
-import android.widget.Filter;
-import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
-import android.widget.AdapterView.OnItemClickListener;
import java.util.ArrayList;
import java.util.HashMap;
@@ -104,6 +85,12 @@ public class RunningServices extends ListActivity
int mProcessBgColor;
+ TextView mBackgroundProcessText;
+ TextView mForegroundProcessText;
+
+ int mLastNumBackgroundProcesses = -1;
+ int mLastNumForegroundProcesses = -1;
+
Dialog mCurDialog;
class ActiveItem {
@@ -114,18 +101,27 @@ public class RunningServices extends ListActivity
long mFirstRunTime;
void updateTime(Context context) {
- if (mItem.mActiveSince >= 0) {
- mHolder.size.setText(DateUtils.formatElapsedTime(mBuilder,
- (SystemClock.uptimeMillis()-mFirstRunTime)/1000));
+ if (mItem.mIsProcess) {
+ String size = mItem.mSizeStr != null ? mItem.mSizeStr : "";
+ if (!size.equals(mItem.mCurSizeStr)) {
+ mItem.mCurSizeStr = size;
+ mHolder.size.setText(size);
+ }
} else {
- mHolder.size.setText(context.getResources().getText(
- R.string.service_restarting));
+ if (mItem.mActiveSince >= 0) {
+ mHolder.size.setText(DateUtils.formatElapsedTime(mBuilder,
+ (SystemClock.uptimeMillis()-mFirstRunTime)/1000));
+ } else {
+ mHolder.size.setText(context.getResources().getText(
+ R.string.service_restarting));
+ }
}
}
}
static class BaseItem {
- boolean mIsProcess;
+ final boolean mIsProcess;
+
PackageItemInfo mPackageInfo;
CharSequence mDisplayLabel;
String mLabel;
@@ -136,21 +132,119 @@ public class RunningServices extends ListActivity
long mActiveSince;
long mSize;
String mSizeStr;
+ String mCurSizeStr;
boolean mNeedDivider;
+
+ public BaseItem(boolean isProcess) {
+ mIsProcess = isProcess;
+ }
}
static class ServiceItem extends BaseItem {
ActivityManager.RunningServiceInfo mRunningService;
ServiceInfo mServiceInfo;
boolean mShownAsStarted;
+
+ public ServiceItem() {
+ super(false);
+ }
}
static class ProcessItem extends BaseItem {
final HashMap mServices
= new HashMap();
- int mUid;
+ final SparseArray mDependentProcesses
+ = new SparseArray();
+
+ final int mUid;
+ final String mProcessName;
int mPid;
+ ProcessItem mClient;
+ int mLastNumDependentProcesses;
+
+ int mRunningSeq;
+ ActivityManager.RunningAppProcessInfo mRunningProcessInfo;
+
+ public ProcessItem(int uid, String processName) {
+ super(true);
+ mDescription = processName;
+ mUid = uid;
+ mProcessName = processName;
+ }
+
+ void ensureLabel(PackageManager pm) {
+ if (mLabel != null) {
+ return;
+ }
+
+ try {
+ ApplicationInfo ai = pm.getApplicationInfo(mProcessName, 0);
+ if (ai.uid == mUid) {
+ mDisplayLabel = ai.loadLabel(pm);
+ mLabel = mDisplayLabel.toString();
+ mPackageInfo = ai;
+ return;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+
+ // If we couldn't get information about the overall
+ // process, try to find something about the uid.
+ String[] pkgs = pm.getPackagesForUid(mUid);
+
+ // If there is one package with this uid, that is what we want.
+ if (pkgs.length == 1) {
+ try {
+ ApplicationInfo ai = pm.getApplicationInfo(pkgs[0], 0);
+ mDisplayLabel = ai.loadLabel(pm);
+ mLabel = mDisplayLabel.toString();
+ mPackageInfo = ai;
+ return;
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+
+ // If there are multiple, see if one gives us the official name
+ // for this uid.
+ for (String name : pkgs) {
+ try {
+ PackageInfo pi = pm.getPackageInfo(name, 0);
+ if (pi.sharedUserLabel != 0) {
+ CharSequence nm = pm.getText(name,
+ pi.sharedUserLabel, pi.applicationInfo);
+ if (nm != null) {
+ mDisplayLabel = nm;
+ mLabel = nm.toString();
+ mPackageInfo = pi.applicationInfo;
+ return;
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+
+ // If still don't have anything to display, just use the
+ // service info.
+ if (mServices.size() > 0) {
+ mPackageInfo = mServices.values().iterator().next()
+ .mServiceInfo.applicationInfo;
+ mDisplayLabel = mPackageInfo.loadLabel(pm);
+ mLabel = mDisplayLabel.toString();
+ return;
+ }
+
+ // Finally... whatever, just pick the first package's name.
+ try {
+ ApplicationInfo ai = pm.getApplicationInfo(pkgs[0], 0);
+ mDisplayLabel = ai.loadLabel(pm);
+ mLabel = mDisplayLabel.toString();
+ mPackageInfo = ai;
+ return;
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+
boolean updateService(Context context,
ActivityManager.RunningServiceInfo service) {
final PackageManager pm = context.getPackageManager();
@@ -211,16 +305,89 @@ public class RunningServices extends ListActivity
return changed;
}
+
+ boolean updateSize(Context context) {
+ boolean changed = false;
+
+ if (mPid != 0 && mSize == 0) {
+ final int NP = mDependentProcesses.size();
+ for (int i=0; i dest) {
+ final int NP = mDependentProcesses.size();
+ for (int i=0; i> mProcesses
= new SparseArray>();
+ final SparseArray mActiveProcesses
+ = new SparseArray();
+
+ // Temporary for finding process dependencies.
+ final SparseArray mRunningProcesses
+ = new SparseArray();
final ArrayList mItems = new ArrayList();
int mSequence = 0;
+ int mNumBackgroundProcesses;
+ int mNumForegroundProcesses;
+
boolean update(Context context, ActivityManager am) {
final PackageManager pm = context.getPackageManager();
@@ -230,10 +397,7 @@ public class RunningServices extends ListActivity
List services
= am.getRunningServices(MAX_SERVICES);
- if (services == null) {
- return false;
- }
- final int NS = services.size();
+ final int NS = services != null ? services.size() : 0;
for (int i=0; i processes
+ = am.getRunningAppProcesses();
+ final int NP = processes != null ? processes.size() : 0;
+ for (int i=0; i=
+ ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
+ mNumBackgroundProcesses++;
+ } else if (proc.mRunningProcessInfo.importance <=
+ ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
+ mNumForegroundProcesses++;
}
}
}
- // Look for anything that no longer exists...
+ // Look for services and their primary processes that no longer exist...
for (int i=0; i procs = mProcesses.valueAt(i);
Iterator pit = procs.values().iterator();
while (pit.hasNext()) {
ProcessItem pi = pit.next();
- if (pi.mCurSeq != mSequence) {
+ if (pi.mCurSeq == mSequence) {
+ pi.ensureLabel(pm);
+ changed |= pi.updateSize(context);
+ if (pi.mPid == 0) {
+ // Sanity: a non-process can't be dependent on
+ // anything.
+ pi.mDependentProcesses.clear();
+ }
+ } else {
changed = true;
pit.remove();
if (procs.size() == 0) {
mProcesses.remove(mProcesses.keyAt(i));
}
+ if (pi.mPid != 0) {
+ mActiveProcesses.remove(pi.mPid);
+ }
continue;
}
Iterator sit = pi.mServices.values().iterator();
@@ -365,7 +568,11 @@ public class RunningServices extends ListActivity
for (int i=0; i