Merge "Fix issue #10948509: Crash in procstats when there is no data" into klp-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
768dc8f729
@@ -801,7 +801,8 @@
|
||||
<activity android:name="Settings$AppOpsSummaryActivity"
|
||||
android:label="@string/app_ops_settings"
|
||||
android:taskAffinity=""
|
||||
android:excludeFromRecents="true">
|
||||
android:excludeFromRecents="true"
|
||||
android:enabled="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<action android:name="android.settings.APP_OPS_SETTINGS" />
|
||||
|
@@ -21,8 +21,8 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import com.android.internal.app.ProcessStats;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -31,11 +31,12 @@ import java.util.Comparator;
|
||||
|
||||
public final class ProcStatsEntry implements Parcelable {
|
||||
private static final String TAG = "ProcStatsEntry";
|
||||
private static boolean DEBUG = ProcessStatsUi.DEBUG;
|
||||
|
||||
final String mPackage;
|
||||
final int mUid;
|
||||
final String mName;
|
||||
final boolean mUnique;
|
||||
final ArrayList<String> mPackages = new ArrayList<String>();
|
||||
final long mDuration;
|
||||
final long mAvgPss;
|
||||
final long mMaxPss;
|
||||
@@ -45,33 +46,35 @@ public final class ProcStatsEntry implements Parcelable {
|
||||
|
||||
String mBestTargetPackage;
|
||||
|
||||
ArrayList<Service> mServices = new ArrayList<Service>(2);
|
||||
ArrayMap<String, ArrayList<Service>> mServices = new ArrayMap<String, ArrayList<Service>>(1);
|
||||
|
||||
public ApplicationInfo mUiTargetApp;
|
||||
public String mUiLabel;
|
||||
public String mUiBaseLabel;
|
||||
public String mUiPackage;
|
||||
|
||||
public ProcStatsEntry(ProcessStats.ProcessState proc,
|
||||
public ProcStatsEntry(ProcessStats.ProcessState proc, String packageName,
|
||||
ProcessStats.ProcessDataCollection tmpTotals, boolean useUss, boolean weightWithTime) {
|
||||
ProcessStats.computeProcessData(proc, tmpTotals, 0);
|
||||
mPackage = proc.mPackage;
|
||||
mUid = proc.mUid;
|
||||
mName = proc.mName;
|
||||
mUnique = proc.mCommonProcess == proc;
|
||||
mPackages.add(packageName);
|
||||
mDuration = tmpTotals.totalTime;
|
||||
mAvgPss = tmpTotals.avgPss;
|
||||
mMaxPss = tmpTotals.maxPss;
|
||||
mAvgUss = tmpTotals.avgUss;
|
||||
mMaxUss = tmpTotals.maxUss;
|
||||
mWeight = (weightWithTime ? mDuration : 1) * (useUss ? mAvgUss : mAvgPss);
|
||||
if (DEBUG) Log.d(TAG, "New proc entry " + proc.mName + ": dur=" + mDuration
|
||||
+ " avgpss=" + mAvgPss + " weight=" + mWeight);
|
||||
}
|
||||
|
||||
public ProcStatsEntry(Parcel in) {
|
||||
mPackage = in.readString();
|
||||
mUid = in.readInt();
|
||||
mName = in.readString();
|
||||
mUnique = in.readInt() != 0;
|
||||
in.readStringList(mPackages);
|
||||
mDuration = in.readLong();
|
||||
mAvgPss = in.readLong();
|
||||
mMaxPss = in.readLong();
|
||||
@@ -79,40 +82,118 @@ public final class ProcStatsEntry implements Parcelable {
|
||||
mMaxUss = in.readLong();
|
||||
mWeight = in.readLong();
|
||||
mBestTargetPackage = in.readString();
|
||||
in.readTypedList(mServices, Service.CREATOR);
|
||||
final int N = in.readInt();
|
||||
if (N > 0) {
|
||||
mServices.ensureCapacity(N);
|
||||
for (int i=0; i<N; i++) {
|
||||
String key = in.readString();
|
||||
ArrayList<Service> value = new ArrayList<Service>();
|
||||
in.readTypedList(value, Service.CREATOR);
|
||||
mServices.append(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void evaluateTargetPackage(ProcessStats stats, ProcessStats.ProcessDataCollection totals,
|
||||
Comparator<ProcStatsEntry> compare, boolean useUss, boolean weightWithTime) {
|
||||
public void addPackage(String packageName) {
|
||||
mPackages.add(packageName);
|
||||
}
|
||||
|
||||
public void evaluateTargetPackage(PackageManager pm, ProcessStats stats,
|
||||
ProcessStats.ProcessDataCollection totals, Comparator<ProcStatsEntry> compare,
|
||||
boolean useUss, boolean weightWithTime) {
|
||||
mBestTargetPackage = null;
|
||||
if (mUnique) {
|
||||
mBestTargetPackage = mPackage;
|
||||
if (mPackages.size() == 1) {
|
||||
if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": single pkg " + mPackages.get(0));
|
||||
mBestTargetPackage = mPackages.get(0);
|
||||
} 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);
|
||||
for (int iproc=0, NPROC=pkgState.mProcesses.size(); iproc<NPROC; iproc++) {
|
||||
ProcessStats.ProcessState subProc =
|
||||
pkgState.mProcesses.valueAt(iproc);
|
||||
if (subProc.mName.equals(mName)) {
|
||||
subProcs.add(new ProcStatsEntry(subProc, totals, useUss,
|
||||
weightWithTime));
|
||||
}
|
||||
}
|
||||
for (int ipkg=0; ipkg<mPackages.size(); ipkg++) {
|
||||
ProcessStats.PackageState pkgState = stats.mPackages.get(mPackages.get(ipkg), mUid);
|
||||
if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ", pkg "
|
||||
+ mPackages.get(ipkg) + ":");
|
||||
if (pkgState == null) {
|
||||
Log.w(TAG, "No package state found for " + mPackages.get(ipkg) + "/"
|
||||
+ mUid + " in process " + mName);
|
||||
continue;
|
||||
}
|
||||
ProcessStats.ProcessState pkgProc = pkgState.mProcesses.get(mName);
|
||||
if (pkgProc == null) {
|
||||
Log.w(TAG, "No process " + mName + " found in package state "
|
||||
+ mPackages.get(ipkg) + "/" + mUid);
|
||||
continue;
|
||||
}
|
||||
subProcs.add(new ProcStatsEntry(pkgProc, pkgState.mPackageName, totals, useUss,
|
||||
weightWithTime));
|
||||
}
|
||||
if (subProcs.size() > 1) {
|
||||
Collections.sort(subProcs, compare);
|
||||
if (subProcs.get(0).mWeight > (subProcs.get(1).mWeight*3)) {
|
||||
if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": best pkg "
|
||||
+ subProcs.get(0).mPackage + " weight " + subProcs.get(0).mWeight
|
||||
+ " better than " + subProcs.get(1).mPackage
|
||||
+ " weight " + subProcs.get(1).mWeight);
|
||||
mBestTargetPackage = subProcs.get(0).mPackage;
|
||||
return;
|
||||
}
|
||||
// Couldn't find one that is best by weight, let's decide on best another
|
||||
// way: the one that has the longest running service, accounts for at least
|
||||
// half of the maximum weight, and has specified an explicit app icon.
|
||||
long maxWeight = subProcs.get(0).mWeight;
|
||||
long bestRunTime = -1;
|
||||
for (int i=0; i<subProcs.size(); i++) {
|
||||
if (subProcs.get(i).mWeight < (maxWeight/2)) {
|
||||
if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": pkg "
|
||||
+ subProcs.get(i).mPackage + " weight " + subProcs.get(i).mWeight
|
||||
+ " too small");
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
ApplicationInfo ai = pm.getApplicationInfo(subProcs.get(i).mPackage, 0);
|
||||
if (ai.icon == 0) {
|
||||
if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": pkg "
|
||||
+ subProcs.get(i).mPackage + " has no icon");
|
||||
continue;
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": pkg "
|
||||
+ subProcs.get(i).mPackage + " failed finding app info");
|
||||
continue;
|
||||
}
|
||||
ArrayList<Service> subProcServices = null;
|
||||
for (int isp=0, NSP=mServices.size(); isp<NSP; isp++) {
|
||||
ArrayList<Service> subServices = mServices.valueAt(isp);
|
||||
if (subServices.get(0).mPackage.equals(subProcs.get(i).mPackage)) {
|
||||
subProcServices = subServices;
|
||||
break;
|
||||
}
|
||||
}
|
||||
long thisRunTime = 0;
|
||||
if (subProcServices != null) {
|
||||
for (int iss=0, NSS=subProcServices.size(); iss<NSS; iss++) {
|
||||
Service service = subProcServices.get(iss);
|
||||
if (service.mDuration > thisRunTime) {
|
||||
if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": pkg "
|
||||
+ subProcs.get(i).mPackage + " service " + service.mName
|
||||
+ " run time is " + service.mDuration);
|
||||
thisRunTime = service.mDuration;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (thisRunTime > bestRunTime) {
|
||||
if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": pkg "
|
||||
+ subProcs.get(i).mPackage + " new best run time " + thisRunTime);
|
||||
mBestTargetPackage = subProcs.get(i).mPackage;
|
||||
bestRunTime = thisRunTime;
|
||||
} else {
|
||||
if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": pkg "
|
||||
+ subProcs.get(i).mPackage + " run time " + thisRunTime
|
||||
+ " not as good as last " + bestRunTime);
|
||||
}
|
||||
}
|
||||
} else if (subProcs.size() == 1) {
|
||||
mBestTargetPackage = subProcs.get(0).mPackage;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,7 +259,12 @@ public final class ProcStatsEntry implements Parcelable {
|
||||
}
|
||||
|
||||
public void addService(ProcessStats.ServiceState svc) {
|
||||
mServices.add(new Service(svc));
|
||||
ArrayList<Service> services = mServices.get(svc.mPackage);
|
||||
if (services == null) {
|
||||
services = new ArrayList<Service>();
|
||||
mServices.put(svc.mPackage, services);
|
||||
}
|
||||
services.add(new Service(svc));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -191,7 +277,7 @@ public final class ProcStatsEntry implements Parcelable {
|
||||
dest.writeString(mPackage);
|
||||
dest.writeInt(mUid);
|
||||
dest.writeString(mName);
|
||||
dest.writeInt(mUnique ? 1 : 0);
|
||||
dest.writeStringList(mPackages);
|
||||
dest.writeLong(mDuration);
|
||||
dest.writeLong(mAvgPss);
|
||||
dest.writeLong(mMaxPss);
|
||||
@@ -199,7 +285,12 @@ public final class ProcStatsEntry implements Parcelable {
|
||||
dest.writeLong(mMaxUss);
|
||||
dest.writeLong(mWeight);
|
||||
dest.writeString(mBestTargetPackage);
|
||||
dest.writeTypedList(mServices);
|
||||
final int N = mServices.size();
|
||||
dest.writeInt(N);
|
||||
for (int i=0; i<N; i++) {
|
||||
dest.writeString(mServices.keyAt(i));
|
||||
dest.writeTypedList(mServices.valueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<ProcStatsEntry> CREATOR
|
||||
|
@@ -168,6 +168,23 @@ public class ProcessStatsDetail extends Fragment implements Button.OnClickListen
|
||||
}
|
||||
}
|
||||
|
||||
private void addPackageHeaderItem(ViewGroup parent, String packageName) {
|
||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
ViewGroup item = (ViewGroup) inflater.inflate(R.layout.running_processes_item,
|
||||
null);
|
||||
parent.addView(item);
|
||||
final ImageView icon = (ImageView) item.findViewById(R.id.icon);
|
||||
TextView nameView = (TextView) item.findViewById(R.id.name);
|
||||
TextView descriptionView = (TextView) item.findViewById(R.id.description);
|
||||
try {
|
||||
ApplicationInfo ai = mPm.getApplicationInfo(packageName, 0);
|
||||
icon.setImageDrawable(ai.loadIcon(mPm));
|
||||
nameView.setText(ai.loadLabel(mPm));
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
}
|
||||
descriptionView.setText(packageName);
|
||||
}
|
||||
|
||||
private void addDetailsItem(ViewGroup parent, CharSequence label, CharSequence value) {
|
||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
ViewGroup item = (ViewGroup) inflater.inflate(R.layout.power_usage_detail_item_text,
|
||||
@@ -204,22 +221,31 @@ public class ProcessStatsDetail extends Fragment implements Button.OnClickListen
|
||||
};
|
||||
|
||||
private void fillServicesSection() {
|
||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
if (mEntry.mServices.size() > 0) {
|
||||
ArrayList<ProcStatsEntry.Service> services =
|
||||
(ArrayList<ProcStatsEntry.Service>)mEntry.mServices.clone();
|
||||
Collections.sort(services, sServiceCompare);
|
||||
for (int i=0; i<services.size(); i++) {
|
||||
ProcStatsEntry.Service service = services.get(i);
|
||||
String label = service.mName;
|
||||
int tail = label.lastIndexOf('.');
|
||||
if (tail >= 0 && tail < (label.length()-1)) {
|
||||
label = label.substring(tail+1);
|
||||
boolean addPackageSections = false;
|
||||
if (mEntry.mServices.size() > 1
|
||||
|| !mEntry.mServices.valueAt(0).get(0).mPackage.equals(mEntry.mPackage)) {
|
||||
addPackageSections = true;
|
||||
}
|
||||
for (int ip=0; ip<mEntry.mServices.size(); ip++) {
|
||||
ArrayList<ProcStatsEntry.Service> services =
|
||||
(ArrayList<ProcStatsEntry.Service>)mEntry.mServices.valueAt(ip).clone();
|
||||
Collections.sort(services, sServiceCompare);
|
||||
if (addPackageSections) {
|
||||
addPackageHeaderItem(mServicesParent, services.get(0).mPackage);
|
||||
}
|
||||
for (int is=0; is<services.size(); is++) {
|
||||
ProcStatsEntry.Service service = services.get(is);
|
||||
String label = service.mName;
|
||||
int tail = label.lastIndexOf('.');
|
||||
if (tail >= 0 && tail < (label.length()-1)) {
|
||||
label = label.substring(tail+1);
|
||||
}
|
||||
long duration = service.mDuration;
|
||||
final double percentOfTime = (((double)duration) / mTotalTime) * 100;
|
||||
addDetailsItem(mServicesParent, label, getActivity().getResources().getString(
|
||||
R.string.percentage, (int) Math.ceil(percentOfTime)));
|
||||
}
|
||||
long duration = service.mDuration;
|
||||
final double percentOfTime = (((double)duration) / mTotalTime) * 100;
|
||||
addDetailsItem(mServicesParent, label, getActivity().getResources().getString(
|
||||
R.string.percentage, (int) Math.ceil(percentOfTime)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -45,7 +45,7 @@ public class ProcessStatsPreference extends Preference {
|
||||
public void setPercent(double percentOfWeight, double percentOfTime) {
|
||||
mProgress = (int) Math.ceil(percentOfWeight);
|
||||
mProgressText = getContext().getResources().getString(
|
||||
R.string.percentage, (int) Math.ceil(percentOfTime));
|
||||
R.string.percentage, (int) Math.round(percentOfTime));
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
|
@@ -19,7 +19,6 @@ package com.android.settings.applications;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
@@ -30,7 +29,6 @@ import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceGroup;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.util.TimeUtils;
|
||||
@@ -39,6 +37,7 @@ import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SubMenu;
|
||||
import com.android.internal.app.IProcessStats;
|
||||
import com.android.internal.app.ProcessMap;
|
||||
import com.android.internal.app.ProcessStats;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.Utils;
|
||||
@@ -50,8 +49,8 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class ProcessStatsUi extends PreferenceFragment {
|
||||
private static final String TAG = "ProcessStatsUi";
|
||||
private static final boolean DEBUG = false;
|
||||
static final String TAG = "ProcessStatsUi";
|
||||
static final boolean DEBUG = false;
|
||||
|
||||
private static final String KEY_APP_LIST = "app_list";
|
||||
private static final String KEY_MEM_STATUS = "mem_status";
|
||||
@@ -76,6 +75,10 @@ public class ProcessStatsUi extends PreferenceFragment {
|
||||
return 1;
|
||||
} else if (lhs.mWeight > rhs.mWeight) {
|
||||
return -1;
|
||||
} else if (lhs.mDuration < rhs.mDuration) {
|
||||
return 1;
|
||||
} else if (lhs.mDuration > rhs.mDuration) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -112,7 +115,7 @@ public class ProcessStatsUi extends PreferenceFragment {
|
||||
// batches of 3 hours so we want to allow the time we use to be slightly
|
||||
// smaller than the actual time selected instead of bumping up to 3 hours
|
||||
// beyond it.
|
||||
private static final long DURATION_QUANTUM = 3*60*60*1000;
|
||||
private static final long DURATION_QUANTUM = ProcessStats.COMMIT_PERIOD;
|
||||
private static long[] sDurations = new long[] {
|
||||
3*60*60*1000 - DURATION_QUANTUM/2, 6*60*60*1000 - DURATION_QUANTUM/2,
|
||||
12*60*60*1000 - DURATION_QUANTUM/2, 24*60*60*1000 - DURATION_QUANTUM/2
|
||||
@@ -319,6 +322,12 @@ public class ProcessStatsUi extends PreferenceFragment {
|
||||
ProcessStats.STATE_CACHED_EMPTY
|
||||
};
|
||||
|
||||
private String makeDuration(long time) {
|
||||
StringBuilder sb = new StringBuilder(32);
|
||||
TimeUtils.formatDuration(time, sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void refreshStats() {
|
||||
updateMenus();
|
||||
|
||||
@@ -378,6 +387,7 @@ public class ProcessStatsUi extends PreferenceFragment {
|
||||
|
||||
mTotalTime = ProcessStats.dumpSingleTime(null, null, mStats.mMemFactorDurations,
|
||||
mStats.mMemFactor, mStats.mStartTime, now);
|
||||
if (DEBUG) Log.d(TAG, "Total time of stats: " + makeDuration(mTotalTime));
|
||||
|
||||
LinearColorPreference colors = new LinearColorPreference(getActivity());
|
||||
colors.setOrder(-1);
|
||||
@@ -396,7 +406,7 @@ public class ProcessStatsUi extends PreferenceFragment {
|
||||
+ memTimes[ProcessStats.ADJ_MEM_FACTOR_MODERATE]) / (float)mTotalTime,
|
||||
memTimes[ProcessStats.ADJ_MEM_FACTOR_NORMAL] / (float)mTotalTime);
|
||||
|
||||
ArrayList<ProcStatsEntry> procs = new ArrayList<ProcStatsEntry>();
|
||||
ArrayList<ProcStatsEntry> entries = new ArrayList<ProcStatsEntry>();
|
||||
|
||||
/*
|
||||
ArrayList<ProcessStats.ProcessState> rawProcs = mStats.collectProcessesLocked(
|
||||
@@ -407,50 +417,43 @@ public class ProcessStatsUi extends PreferenceFragment {
|
||||
}
|
||||
*/
|
||||
|
||||
ArrayMap<String, ProcStatsEntry> processes = new ArrayMap<String, ProcStatsEntry>(
|
||||
mStats.mProcesses.getMap().size());
|
||||
for (int ip=0, N=mStats.mProcesses.getMap().size(); ip<N; ip++) {
|
||||
SparseArray<ProcessStats.ProcessState> uids = mStats.mProcesses.getMap().valueAt(ip);
|
||||
for (int iu=0; iu<uids.size(); iu++) {
|
||||
ProcStatsEntry ent = new ProcStatsEntry(uids.valueAt(iu), totals, mUseUss,
|
||||
mStatsType == MENU_TYPE_BACKGROUND);
|
||||
procs.add(ent);
|
||||
processes.put(ent.mName, ent);
|
||||
if (DEBUG) Log.d(TAG, "-------------------- PULLING PROCESSES");
|
||||
|
||||
final ProcessMap<ProcStatsEntry> entriesMap = new ProcessMap<ProcStatsEntry>();
|
||||
for (int ipkg=0, N=mStats.mPackages.getMap().size(); ipkg<N; ipkg++) {
|
||||
final SparseArray<ProcessStats.PackageState> pkgUids
|
||||
= mStats.mPackages.getMap().valueAt(ipkg);
|
||||
for (int iu=0; iu<pkgUids.size(); iu++) {
|
||||
final ProcessStats.PackageState st = pkgUids.valueAt(iu);
|
||||
for (int iproc=0; iproc<st.mProcesses.size(); iproc++) {
|
||||
final ProcessStats.ProcessState pkgProc = st.mProcesses.valueAt(iproc);
|
||||
final ProcessStats.ProcessState proc = mStats.mProcesses.get(pkgProc.mName,
|
||||
pkgProc.mUid);
|
||||
if (proc == null) {
|
||||
Log.w(TAG, "No process found for pkg " + st.mPackageName
|
||||
+ "/" + st.mUid + " proc name " + pkgProc.mName);
|
||||
continue;
|
||||
}
|
||||
ProcStatsEntry ent = entriesMap.get(proc.mName, proc.mUid);
|
||||
if (ent == null) {
|
||||
ent = new ProcStatsEntry(proc, st.mPackageName, totals, mUseUss,
|
||||
mStatsType == MENU_TYPE_BACKGROUND);
|
||||
if (ent.mDuration > 0) {
|
||||
if (DEBUG) Log.d(TAG, "Adding proc " + proc.mName + "/"
|
||||
+ proc.mUid + ": time=" + makeDuration(ent.mDuration) + " ("
|
||||
+ ((((double)ent.mDuration) / mTotalTime) * 100) + "%)"
|
||||
+ " pss=" + ent.mAvgPss);
|
||||
entriesMap.put(proc.mName, proc.mUid, ent);
|
||||
entries.add(ent);
|
||||
}
|
||||
} else {
|
||||
ent.addPackage(st.mPackageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(procs, sEntryCompare);
|
||||
while (procs.size() > MAX_ITEMS_TO_LIST) {
|
||||
procs.remove(procs.size()-1);
|
||||
}
|
||||
|
||||
long maxWeight = 0;
|
||||
for (int i=0, N=(procs != null ? procs.size() : 0); i<N; i++) {
|
||||
ProcStatsEntry proc = procs.get(i);
|
||||
if (maxWeight < proc.mWeight) {
|
||||
maxWeight = proc.mWeight;
|
||||
}
|
||||
}
|
||||
mMaxWeight = maxWeight;
|
||||
|
||||
for (int i=0, N=(procs != null ? procs.size() : 0); i<N; i++) {
|
||||
ProcStatsEntry proc = procs.get(i);
|
||||
final double percentOfWeight = (((double)proc.mWeight) / maxWeight) * 100;
|
||||
final double percentOfTime = (((double)proc.mDuration) / mTotalTime) * 100;
|
||||
if (percentOfWeight < 1) break;
|
||||
ProcessStatsPreference pref = new ProcessStatsPreference(getActivity(), null, proc);
|
||||
proc.evaluateTargetPackage(mStats, totals, sEntryCompare, mUseUss,
|
||||
mStatsType == MENU_TYPE_BACKGROUND);
|
||||
proc.retrieveUiData(pm);
|
||||
pref.setTitle(proc.mUiLabel);
|
||||
if (proc.mUiTargetApp != null) {
|
||||
pref.setIcon(proc.mUiTargetApp.loadIcon(pm));
|
||||
}
|
||||
pref.setOrder(i);
|
||||
pref.setPercent(percentOfWeight, percentOfTime);
|
||||
mAppListGroup.addPreference(pref);
|
||||
if (mAppListGroup.getPreferenceCount() > (MAX_ITEMS_TO_LIST+1)) break;
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "-------------------- MAPPING SERVICES");
|
||||
|
||||
// Add in service info.
|
||||
if (mStatsType == MENU_TYPE_BACKGROUND) {
|
||||
@@ -461,13 +464,85 @@ public class ProcessStatsUi extends PreferenceFragment {
|
||||
for (int is=0, NS=ps.mServices.size(); is<NS; is++) {
|
||||
ProcessStats.ServiceState ss = ps.mServices.valueAt(is);
|
||||
if (ss.mProcessName != null) {
|
||||
ProcStatsEntry ent = processes.get(ss.mProcessName);
|
||||
ent.addService(ss);
|
||||
ProcStatsEntry ent = entriesMap.get(ss.mProcessName, uids.keyAt(iu));
|
||||
if (ent != null) {
|
||||
if (DEBUG) Log.d(TAG, "Adding service " + ps.mPackageName
|
||||
+ "/" + ss.mName + "/" + uids.keyAt(iu) + " to proc "
|
||||
+ ss.mProcessName);
|
||||
ent.addService(ss);
|
||||
} else {
|
||||
Log.w(TAG, "No process " + ss.mProcessName + "/" + uids.keyAt(iu)
|
||||
+ " for service " + ss.mName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
SparseArray<ArrayMap<String, ProcStatsEntry>> processes
|
||||
= new SparseArray<ArrayMap<String, ProcStatsEntry>>();
|
||||
for (int ip=0, N=mStats.mProcesses.getMap().size(); ip<N; ip++) {
|
||||
SparseArray<ProcessStats.ProcessState> uids = mStats.mProcesses.getMap().valueAt(ip);
|
||||
for (int iu=0; iu<uids.size(); iu++) {
|
||||
ProcessStats.ProcessState st = uids.valueAt(iu);
|
||||
ProcStatsEntry ent = new ProcStatsEntry(st, totals, mUseUss,
|
||||
mStatsType == MENU_TYPE_BACKGROUND);
|
||||
if (ent.mDuration > 0) {
|
||||
if (DEBUG) Log.d(TAG, "Adding proc " + st.mName + "/" + st.mUid + ": time="
|
||||
+ makeDuration(ent.mDuration) + " ("
|
||||
+ ((((double)ent.mDuration) / mTotalTime) * 100) + "%)");
|
||||
procs.add(ent);
|
||||
ArrayMap<String, ProcStatsEntry> uidProcs = processes.get(ent.mUid);
|
||||
if (uidProcs == null) {
|
||||
uidProcs = new ArrayMap<String, ProcStatsEntry>();
|
||||
processes.put(ent.mUid, uidProcs);
|
||||
}
|
||||
uidProcs.put(ent.mName, ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Collections.sort(entries, sEntryCompare);
|
||||
|
||||
long maxWeight = 1;
|
||||
for (int i=0, N=(entries != null ? entries.size() : 0); i<N; i++) {
|
||||
ProcStatsEntry proc = entries.get(i);
|
||||
if (maxWeight < proc.mWeight) {
|
||||
maxWeight = proc.mWeight;
|
||||
}
|
||||
}
|
||||
mMaxWeight = maxWeight;
|
||||
|
||||
if (DEBUG) Log.d(TAG, "-------------------- BUILDING UI");
|
||||
|
||||
for (int i=0, N=(entries != null ? entries.size() : 0); i<N; i++) {
|
||||
ProcStatsEntry proc = entries.get(i);
|
||||
final double percentOfWeight = (((double)proc.mWeight) / maxWeight) * 100;
|
||||
final double percentOfTime = (((double)proc.mDuration) / mTotalTime) * 100;
|
||||
if (percentOfWeight < 1 && percentOfTime < 33) {
|
||||
if (DEBUG) Log.d(TAG, "Skipping " + proc.mName + " weight=" + percentOfWeight
|
||||
+ " time=" + percentOfTime);
|
||||
continue;
|
||||
}
|
||||
ProcessStatsPreference pref = new ProcessStatsPreference(getActivity(), null, proc);
|
||||
proc.evaluateTargetPackage(pm, mStats, totals, sEntryCompare, mUseUss,
|
||||
mStatsType == MENU_TYPE_BACKGROUND);
|
||||
proc.retrieveUiData(pm);
|
||||
pref.setTitle(proc.mUiLabel);
|
||||
if (proc.mUiTargetApp != null) {
|
||||
pref.setIcon(proc.mUiTargetApp.loadIcon(pm));
|
||||
}
|
||||
pref.setOrder(i);
|
||||
pref.setPercent(percentOfWeight, percentOfTime);
|
||||
mAppListGroup.addPreference(pref);
|
||||
if (mAppListGroup.getPreferenceCount() > (MAX_ITEMS_TO_LIST+1)) {
|
||||
if (DEBUG) Log.d(TAG, "Done with UI, hit item limit!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void load() {
|
||||
|
Reference in New Issue
Block a user