diff --git a/res/values/strings.xml b/res/values/strings.xml
index feab24ebebd..b787c8dbe2e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3550,12 +3550,14 @@
-
+
Process Stats
-
+
Geeky stats about running processes
-
+
Memory use
+
+ Over %1$s
diff --git a/src/com/android/settings/applications/ProcStatsEntry.java b/src/com/android/settings/applications/ProcStatsEntry.java
new file mode 100644
index 00000000000..dec283f1b73
--- /dev/null
+++ b/src/com/android/settings/applications/ProcStatsEntry.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import com.android.internal.app.ProcessStats;
+
+public class ProcStatsEntry {
+ final String mPackage;
+ final int mUid;
+ final String mName;
+ final boolean mUnique;
+ final long mDuration;
+ final long mAvgPss;
+ final long mWeight;
+
+ ProcStatsEntry(ProcessStats.ProcessState proc, ProcessStats.ProcessDataCollection tmpTotals) {
+ ProcessStats.computeProcessData(proc, tmpTotals, 0);
+ mPackage = proc.mPackage;
+ mUid = proc.mUid;
+ mName = proc.mName;
+ mUnique = proc.mCommonProcess == proc;
+ mDuration = tmpTotals.totalTime;
+ mAvgPss = tmpTotals.avgPss;
+ mWeight = mDuration * mAvgPss;
+ }
+}
diff --git a/src/com/android/settings/applications/ProcessStatsPreference.java b/src/com/android/settings/applications/ProcessStatsPreference.java
index 1b9e85207d3..64ab0b676f3 100644
--- a/src/com/android/settings/applications/ProcessStatsPreference.java
+++ b/src/com/android/settings/applications/ProcessStatsPreference.java
@@ -36,9 +36,10 @@ public class ProcessStatsPreference extends Preference {
setIcon(icon != null ? icon : new ColorDrawable(0));
}
- public void setPercent(double percentOfTotal, long pss) {
- mProgress = (int) Math.ceil(percentOfTotal);
- mProgressText = pss > 0 ? Formatter.formatShortFileSize(getContext(), pss) : "";
+ public void setPercent(double percentOfWeight, double percentOfTime) {
+ mProgress = (int) Math.ceil(percentOfWeight);
+ mProgressText = getContext().getResources().getString(
+ R.string.percentage, (int) Math.ceil(percentOfTime));
notifyChanged();
}
diff --git a/src/com/android/settings/applications/ProcessStatsUi.java b/src/com/android/settings/applications/ProcessStatsUi.java
index 6434e9efe60..3632288a27f 100644
--- a/src/com/android/settings/applications/ProcessStatsUi.java
+++ b/src/com/android/settings/applications/ProcessStatsUi.java
@@ -31,16 +31,22 @@ import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
+import android.text.format.DateFormat;
import android.util.Log;
+import android.util.TimeUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import com.android.internal.app.IProcessStats;
import com.android.internal.app.ProcessStats;
import com.android.settings.R;
+import com.android.settings.fuelgauge.Utils;
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
public class ProcessStatsUi extends PreferenceFragment {
private static final String TAG = "ProcessStatsUi";
@@ -161,6 +167,15 @@ public class ProcessStatsUi extends PreferenceFragment {
mMemStatusPref.setOrder(-2);
mAppListGroup.addPreference(mMemStatusPref);
+ String durationString = Utils.formatElapsedTime(getActivity(),
+ mStats.mTimePeriodEndRealtime-mStats.mTimePeriodStartRealtime);
+ mMemStatusPref.setTitle(getActivity().getString(R.string.process_stats_total_duration,
+ durationString));
+ /*
+ mMemStatusPref.setTitle(DateFormat.format(DateFormat.getBestDateTimePattern(
+ getActivity().getResources().getConfiguration().locale,
+ "MMMM dd, yyyy h:mm a"), mStats.mTimePeriodStartClock));
+ */
/*
BatteryHistoryPreference hist = new BatteryHistoryPreference(getActivity(), mStats);
hist.setOrder(-1);
@@ -176,45 +191,73 @@ public class ProcessStatsUi extends PreferenceFragment {
mTotalTime = ProcessStats.dumpSingleTime(null, null, mStats.mMemFactorDurations,
mStats.mMemFactor, mStats.mStartTime, now);
- ArrayList procs = mStats.collectProcessesLocked(
+ ArrayList rawProcs = mStats.collectProcessesLocked(
ProcessStats.ALL_SCREEN_ADJ, ProcessStats.ALL_MEM_ADJ,
ProcessStats.BACKGROUND_PROC_STATES, now, null);
final PackageManager pm = getActivity().getPackageManager();
+ ArrayList procs = new ArrayList();
+ for (int i=0, N=(rawProcs != null ? rawProcs.size() : 0); i() {
+ @Override
+ public int compare(ProcStatsEntry lhs, ProcStatsEntry rhs) {
+ if (lhs.mWeight < rhs.mWeight) {
+ return 1;
+ } else if (lhs.mWeight > rhs.mWeight) {
+ return -1;
+ }
+ return 0;
+ }
+ });
+ 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 off) {
+ if (proc.mName.startsWith(proc.mPackage)) {
+ int off = proc.mPackage.length();
+ if (proc.mName.length() > off) {
off++;
}
- label = name + " (" + ps.mName.substring(off) + ")";
+ label = name + " (" + proc.mName.substring(off) + ")";
} else {
- label = name + " (" + ps.mName + ")";
+ label = name + " (" + proc.mName + ")";
}
}
} catch (PackageManager.NameNotFoundException e) {
}
}
if (targetApp == null) {
- String[] packages = pm.getPackagesForUid(ps.mUid);
+ String[] packages = pm.getPackagesForUid(proc.mUid);
for (String pkgName : packages) {
try {
final PackageInfo pi = pm.getPackageInfo(pkgName,
@@ -226,9 +269,10 @@ public class ProcessStatsUi extends PreferenceFragment {
final CharSequence nm = pm.getText(pkgName,
pi.sharedUserLabel, pi.applicationInfo);
if (nm != null) {
- label = nm.toString() + " (" + ps.mName + ")";
+ label = nm.toString() + " (" + proc.mName + ")";
} else {
- label = targetApp.loadLabel(pm).toString() + " (" + ps.mName + ")";
+ label = targetApp.loadLabel(pm).toString() + " ("
+ + proc.mName + ")";
}
break;
}
@@ -240,9 +284,8 @@ public class ProcessStatsUi extends PreferenceFragment {
if (targetApp != null) {
pref.setIcon(targetApp.loadIcon(pm));
}
- pref.setOrder(N+100-i);
- ProcessStats.computeProcessData(ps, totals, now);
- pref.setPercent(percentOfTotal, totals.avgPss * 1024);
+ pref.setOrder(i);
+ pref.setPercent(percentOfWeight, percentOfTime);
mAppListGroup.addPreference(pref);
if (mAppListGroup.getPreferenceCount() > (MAX_ITEMS_TO_LIST+1)) break;
}
@@ -252,16 +295,42 @@ public class ProcessStatsUi extends PreferenceFragment {
try {
ArrayList fds = new ArrayList();
byte[] data = mProcessStats.getCurrentStats(fds);
- for (int i=0; i 0 && (mStats.mTimePeriodEndRealtime-mStats.mTimePeriodStartRealtime)
+ < (24*60*60*1000)) {
+ Log.i(TAG, "Not enough data, loading next file @ " + i);
+ ProcessStats stats = new ProcessStats(false);
+ InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(fds.get(i));
+ stats.read(stream);
+ try {
+ stream.close();
+ } catch (IOException e) {
+ }
+ if (stats.mReadError == null) {
+ mStats.add(stats);
+ StringBuilder sb = new StringBuilder();
+ sb.append("Added stats: ");
+ sb.append(stats.mTimePeriodStartClockStr);
+ sb.append(", over ");
+ TimeUtils.formatDuration(
+ stats.mTimePeriodEndRealtime-stats.mTimePeriodStartRealtime, sb);
+ Log.i(TAG, sb.toString());
+ } else {
+ Log.w(TAG, "Read error: " + stats.mReadError);
+ }
+ i--;
+ }
+ while (i >= 0) {
+ try {
+ fds.get(i).close();
+ } catch (IOException e) {
+ }
+ i--;
+ }
} catch (RemoteException e) {
Log.e(TAG, "RemoteException:", e);
}