diff options
Diffstat (limited to 'src/com/android/settings/applications/ProcStatsEntry.java')
-rw-r--r-- | src/com/android/settings/applications/ProcStatsEntry.java | 214 |
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]; + } + }; } } |