summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/applications/ProcStatsEntry.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/settings/applications/ProcStatsEntry.java')
-rw-r--r--src/com/android/settings/applications/ProcStatsEntry.java214
1 files changed, 203 insertions, 11 deletions
diff --git a/src/com/android/settings/applications/ProcStatsEntry.java b/src/com/android/settings/applications/ProcStatsEntry.java
index e180205..cbbfbb7 100644
--- a/src/com/android/settings/applications/ProcStatsEntry.java
+++ b/src/com/android/settings/applications/ProcStatsEntry.java
@@ -16,11 +16,22 @@
package com.android.settings.applications;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+import android.util.SparseArray;
import com.android.internal.app.ProcessStats;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+public final class ProcStatsEntry implements Parcelable {
+ private static final String TAG = "ProcStatsEntry";
-public final class ProcStatsEntry {
final String mPackage;
final int mUid;
final String mName;
@@ -29,7 +40,14 @@ public final class ProcStatsEntry {
final long mAvgPss;
final long mWeight;
- ArrayList<Service> mServices;
+ String mBestTargetPackage;
+
+ ArrayList<Service> mServices = new ArrayList<Service>(2);
+
+ public ApplicationInfo mUiTargetApp;
+ public String mUiLabel;
+ public String mUiBaseLabel;
+ public String mUiPackage;
public ProcStatsEntry(ProcessStats.ProcessState proc,
ProcessStats.ProcessDataCollection tmpTotals) {
@@ -43,18 +61,156 @@ public final class ProcStatsEntry {
mWeight = mDuration * mAvgPss;
}
+ public ProcStatsEntry(Parcel in) {
+ mPackage = in.readString();
+ mUid = in.readInt();
+ mName = in.readString();
+ mUnique = in.readInt() != 0;
+ mDuration = in.readLong();
+ mAvgPss = in.readLong();
+ mWeight = in.readLong();
+ mBestTargetPackage = in.readString();
+ in.readTypedList(mServices, Service.CREATOR);
+ }
+
+ public void evaluateTargetPackage(ProcessStats stats,
+ ProcessStats.ProcessDataCollection totals, Comparator<ProcStatsEntry> compare) {
+ mBestTargetPackage = null;
+ if (mUnique) {
+ mBestTargetPackage = mPackage;
+ addServices(stats.getPackageStateLocked(mPackage, mUid));
+ } else {
+ // See if there is one significant package that was running here.
+ ArrayList<ProcStatsEntry> subProcs = new ArrayList<ProcStatsEntry>();
+ for (int ipkg=0, NPKG=stats.mPackages.getMap().size(); ipkg<NPKG; ipkg++) {
+ SparseArray<ProcessStats.PackageState> uids
+ = stats.mPackages.getMap().valueAt(ipkg);
+ for (int iu=0, NU=uids.size(); iu<NU; iu++) {
+ if (uids.keyAt(iu) != mUid) {
+ continue;
+ }
+ ProcessStats.PackageState pkgState = uids.valueAt(iu);
+ boolean match = false;
+ for (int iproc=0, NPROC=pkgState.mProcesses.size(); iproc<NPROC; iproc++) {
+ ProcessStats.ProcessState subProc =
+ pkgState.mProcesses.valueAt(iproc);
+ if (subProc.mName.equals(mName)) {
+ match = true;
+ subProcs.add(new ProcStatsEntry(subProc, totals));
+ }
+ }
+ if (match) {
+ addServices(stats.getPackageStateLocked(mPackage, mUid));
+ }
+ }
+ }
+ if (subProcs.size() > 1) {
+ Collections.sort(subProcs, compare);
+ if (subProcs.get(0).mWeight > (subProcs.get(1).mWeight*3)) {
+ mBestTargetPackage = subProcs.get(0).mPackage;
+ }
+ }
+ }
+ }
+
+ public void retrieveUiData(PackageManager pm) {
+ mUiTargetApp = null;
+ mUiLabel = mUiBaseLabel = mName;
+ mUiPackage = mBestTargetPackage;
+ if (mUiPackage != null) {
+ // Only one app associated with this process.
+ try {
+ mUiTargetApp = pm.getApplicationInfo(mUiPackage,
+ PackageManager.GET_DISABLED_COMPONENTS |
+ PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ String name = mUiBaseLabel = mUiTargetApp.loadLabel(pm).toString();
+ if (mName.equals(mUiPackage)) {
+ mUiLabel = name;
+ } else {
+ if (mName.startsWith(mUiPackage)) {
+ int off = mUiPackage.length();
+ if (mName.length() > off) {
+ off++;
+ }
+ mUiLabel = name + " (" + mName.substring(off) + ")";
+ } else {
+ mUiLabel = name + " (" + mName + ")";
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+ if (mUiTargetApp == null) {
+ String[] packages = pm.getPackagesForUid(mUid);
+ if (packages != null) {
+ for (String curPkg : packages) {
+ try {
+ final PackageInfo pi = pm.getPackageInfo(curPkg,
+ PackageManager.GET_DISABLED_COMPONENTS |
+ PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ if (pi.sharedUserLabel != 0) {
+ mUiTargetApp = pi.applicationInfo;
+ final CharSequence nm = pm.getText(curPkg,
+ pi.sharedUserLabel, pi.applicationInfo);
+ if (nm != null) {
+ mUiBaseLabel = nm.toString();
+ mUiLabel = mUiBaseLabel + " (" + mName + ")";
+ } else {
+ mUiBaseLabel = mUiTargetApp.loadLabel(pm).toString();
+ mUiLabel = mUiBaseLabel + " (" + mName + ")";
+ }
+ break;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+ } else {
+ // no current packages for this uid, typically because of uninstall
+ Log.i(TAG, "No package for uid " + mUid);
+ }
+ }
+ }
+
public void addServices(ProcessStats.PackageState pkgState) {
for (int isvc=0, NSVC=pkgState.mServices.size(); isvc<NSVC; isvc++) {
ProcessStats.ServiceState svc = pkgState.mServices.valueAt(isvc);
// XXX can't tell what process it is in!
- if (mServices == null) {
- mServices = new ArrayList<Service>();
- }
mServices.add(new Service(svc));
}
}
- public static final class Service {
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mPackage);
+ dest.writeInt(mUid);
+ dest.writeString(mName);
+ dest.writeInt(mUnique ? 1 : 0);
+ dest.writeLong(mDuration);
+ dest.writeLong(mAvgPss);
+ dest.writeLong(mWeight);
+ dest.writeString(mBestTargetPackage);
+ dest.writeTypedList(mServices);
+ }
+
+ public static final Parcelable.Creator<ProcStatsEntry> CREATOR
+ = new Parcelable.Creator<ProcStatsEntry>() {
+ public ProcStatsEntry createFromParcel(Parcel in) {
+ return new ProcStatsEntry(in);
+ }
+
+ public ProcStatsEntry[] newArray(int size) {
+ return new ProcStatsEntry[size];
+ }
+ };
+
+ public static final class Service implements Parcelable {
final String mPackage;
final String mName;
final long mDuration;
@@ -62,15 +218,51 @@ public final class ProcStatsEntry {
public Service(ProcessStats.ServiceState service) {
mPackage = service.mPackage;
mName = service.mName;
- mDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
+ long startDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
ProcessStats.ServiceState.SERVICE_STARTED,
- ProcessStats.STATE_NOTHING, 0, 0)
- + ProcessStats.dumpSingleServiceTime(null, null, service,
+ ProcessStats.STATE_NOTHING, 0, 0);
+ long bindDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
ProcessStats.ServiceState.SERVICE_BOUND,
- ProcessStats.STATE_NOTHING, 0, 0)
- + ProcessStats.dumpSingleServiceTime(null, null, service,
+ ProcessStats.STATE_NOTHING, 0, 0);
+ long execDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
ProcessStats.ServiceState.SERVICE_EXEC,
ProcessStats.STATE_NOTHING, 0, 0);
+ if (bindDuration > startDuration) {
+ startDuration = bindDuration;
+ }
+ if (execDuration > startDuration) {
+ startDuration = execDuration;
+ }
+ mDuration = startDuration;
}
+
+ public Service(Parcel in) {
+ mPackage = in.readString();
+ mName = in.readString();
+ mDuration = in.readLong();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mPackage);
+ dest.writeString(mName);
+ dest.writeLong(mDuration);
+ }
+
+ public static final Parcelable.Creator<Service> CREATOR
+ = new Parcelable.Creator<Service>() {
+ public Service createFromParcel(Parcel in) {
+ return new Service(in);
+ }
+
+ public Service[] newArray(int size) {
+ return new Service[size];
+ }
+ };
}
}