From 49759af6b06b884d3a1af9dbb120370893744b94 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Sun, 15 Sep 2013 13:22:28 -0700 Subject: [PATCH] Various proc stats UI improvements. - Option to include system processes. - Option to use uss instead of pss sizes. - Option to select type of stats: background processes, foreground (top) processes, cached processes. - Details now shows max mem usage. Change-Id: Ic994564ce846bc1021bf35576feeb9ef095b0e48 --- res/values/strings.xml | 35 +++- .../settings/applications/ProcStatsEntry.java | 23 ++- .../applications/ProcessStatsDetail.java | 11 +- .../settings/applications/ProcessStatsUi.java | 154 ++++++++++++++++-- .../fuelgauge/BatteryHistoryChart.java | 4 +- .../settings/fuelgauge/PowerUsageDetail.java | 2 +- src/com/android/settings/fuelgauge/Utils.java | 35 +++- 7 files changed, 225 insertions(+), 39 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 4b3e26137f8..3b264d48846 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3239,6 +3239,15 @@ %1$ds + + %1$dd %2$dh %3$dm + + + %1$dh %2$dm + + + %1$dm + Usage statistics @@ -3619,16 +3628,38 @@ Memory use - Stats over %1$s + %1$s apps over + %2$s + + Background + + Foreground + + Cached Device memory is currently %1$s - Average RAM use + Average RAM use + + Maximum RAM use Run time Services + + Show system + + Use Uss + + Stats type + + Background + + Foreground + + Cached diff --git a/src/com/android/settings/applications/ProcStatsEntry.java b/src/com/android/settings/applications/ProcStatsEntry.java index d6311dc81ff..830878438f0 100644 --- a/src/com/android/settings/applications/ProcStatsEntry.java +++ b/src/com/android/settings/applications/ProcStatsEntry.java @@ -38,6 +38,9 @@ public final class ProcStatsEntry implements Parcelable { final boolean mUnique; final long mDuration; final long mAvgPss; + final long mMaxPss; + final long mAvgUss; + final long mMaxUss; final long mWeight; String mBestTargetPackage; @@ -50,7 +53,7 @@ public final class ProcStatsEntry implements Parcelable { public String mUiPackage; public ProcStatsEntry(ProcessStats.ProcessState proc, - ProcessStats.ProcessDataCollection tmpTotals) { + ProcessStats.ProcessDataCollection tmpTotals, boolean useUss, boolean weightWithTime) { ProcessStats.computeProcessData(proc, tmpTotals, 0); mPackage = proc.mPackage; mUid = proc.mUid; @@ -58,7 +61,10 @@ public final class ProcStatsEntry implements Parcelable { mUnique = proc.mCommonProcess == proc; mDuration = tmpTotals.totalTime; mAvgPss = tmpTotals.avgPss; - mWeight = mDuration * mAvgPss; + mMaxPss = tmpTotals.maxPss; + mAvgUss = tmpTotals.avgUss; + mMaxUss = tmpTotals.maxUss; + mWeight = (weightWithTime ? mDuration : 1) * (useUss ? mAvgUss : mAvgPss); } public ProcStatsEntry(Parcel in) { @@ -68,13 +74,16 @@ public final class ProcStatsEntry implements Parcelable { mUnique = in.readInt() != 0; mDuration = in.readLong(); mAvgPss = in.readLong(); + mMaxPss = in.readLong(); + mAvgUss = in.readLong(); + mMaxUss = in.readLong(); mWeight = in.readLong(); mBestTargetPackage = in.readString(); in.readTypedList(mServices, Service.CREATOR); } - public void evaluateTargetPackage(ProcessStats stats, - ProcessStats.ProcessDataCollection totals, Comparator compare) { + public void evaluateTargetPackage(ProcessStats stats, ProcessStats.ProcessDataCollection totals, + Comparator compare, boolean useUss, boolean weightWithTime) { mBestTargetPackage = null; if (mUnique) { mBestTargetPackage = mPackage; @@ -93,7 +102,8 @@ public final class ProcStatsEntry implements Parcelable { ProcessStats.ProcessState subProc = pkgState.mProcesses.valueAt(iproc); if (subProc.mName.equals(mName)) { - subProcs.add(new ProcStatsEntry(subProc, totals)); + subProcs.add(new ProcStatsEntry(subProc, totals, useUss, + weightWithTime)); } } } @@ -184,6 +194,9 @@ public final class ProcStatsEntry implements Parcelable { dest.writeInt(mUnique ? 1 : 0); dest.writeLong(mDuration); dest.writeLong(mAvgPss); + dest.writeLong(mMaxPss); + dest.writeLong(mAvgUss); + dest.writeLong(mMaxUss); dest.writeLong(mWeight); dest.writeString(mBestTargetPackage); dest.writeTypedList(mServices); diff --git a/src/com/android/settings/applications/ProcessStatsDetail.java b/src/com/android/settings/applications/ProcessStatsDetail.java index 5ec3b07740c..fad37452363 100644 --- a/src/com/android/settings/applications/ProcessStatsDetail.java +++ b/src/com/android/settings/applications/ProcessStatsDetail.java @@ -52,6 +52,7 @@ public class ProcessStatsDetail extends Fragment implements Button.OnClickListen public static final int ACTION_FORCE_STOP = 1; public static final String EXTRA_ENTRY = "entry"; + public static final String EXTRA_USE_USS = "use_uss"; public static final String EXTRA_MAX_WEIGHT = "max_weight"; public static final String EXTRA_TOTAL_TIME = "total_time"; @@ -59,6 +60,7 @@ public class ProcessStatsDetail extends Fragment implements Button.OnClickListen private DevicePolicyManager mDpm; private ProcStatsEntry mEntry; + private boolean mUseUss; private long mMaxWeight; private long mTotalTime; @@ -83,6 +85,7 @@ public class ProcessStatsDetail extends Fragment implements Button.OnClickListen final Bundle args = getArguments(); mEntry = (ProcStatsEntry)args.getParcelable(EXTRA_ENTRY); mEntry.retrieveUiData(mPm); + mUseUss = args.getBoolean(EXTRA_USE_USS); mMaxWeight = args.getLong(EXTRA_MAX_WEIGHT); mTotalTime = args.getLong(EXTRA_TOTAL_TIME); } @@ -177,8 +180,12 @@ public class ProcessStatsDetail extends Fragment implements Button.OnClickListen } private void fillDetailsSection() { - addDetailsItem(mDetailsParent, getResources().getText(R.string.process_stats_ram_use), - Formatter.formatShortFileSize(getActivity(), mEntry.mAvgPss * 1024)); + addDetailsItem(mDetailsParent, getResources().getText(R.string.process_stats_avg_ram_use), + Formatter.formatShortFileSize(getActivity(), + (mUseUss ? mEntry.mAvgUss : mEntry.mAvgPss) * 1024)); + addDetailsItem(mDetailsParent, getResources().getText(R.string.process_stats_max_ram_use), + Formatter.formatShortFileSize(getActivity(), + (mUseUss ? mEntry.mMaxUss : mEntry.mMaxPss) * 1024)); addDetailsItem(mDetailsParent, getResources().getText(R.string.process_stats_run_time), makePercentString(getResources(), mEntry.mDuration, mTotalTime)); } diff --git a/src/com/android/settings/applications/ProcessStatsUi.java b/src/com/android/settings/applications/ProcessStatsUi.java index 5c5355dc7e2..7601309fd67 100644 --- a/src/com/android/settings/applications/ProcessStatsUi.java +++ b/src/com/android/settings/applications/ProcessStatsUi.java @@ -37,6 +37,7 @@ import android.util.TimeUtils; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import android.view.SubMenu; import com.android.internal.app.IProcessStats; import com.android.internal.app.ProcessStats; import com.android.settings.R; @@ -56,9 +57,14 @@ public class ProcessStatsUi extends PreferenceFragment { private static final String KEY_MEM_STATUS = "mem_status"; private static final int MENU_STATS_REFRESH = Menu.FIRST; - private static final int MENU_HELP = Menu.FIRST + 2; + private static final int MENU_SHOW_SYSTEM = Menu.FIRST + 1; + private static final int MENU_USE_USS = Menu.FIRST + 2; + private static final int MENU_TYPE_BACKGROUND = Menu.FIRST + 3; + private static final int MENU_TYPE_FOREGROUND = Menu.FIRST + 4; + private static final int MENU_TYPE_CACHED = Menu.FIRST + 5; + private static final int MENU_HELP = Menu.FIRST + 6; - static final int MAX_ITEMS_TO_LIST = 20; + static final int MAX_ITEMS_TO_LIST = 40; final static Comparator sEntryCompare = new Comparator() { @Override @@ -79,6 +85,16 @@ public class ProcessStatsUi extends PreferenceFragment { ProcessStats mStats; int mMemState; + private boolean mShowSystem; + private boolean mUseUss; + private int mStatsType; + + private MenuItem mShowSystemMenu; + private MenuItem mUseUssMenu; + private MenuItem mTypeBackgroundMenu; + private MenuItem mTypeForegroundMenu; + private MenuItem mTypeCachedMenu; + private PreferenceGroup mAppListGroup; private Preference mMemStatusPref; @@ -99,6 +115,10 @@ public class ProcessStatsUi extends PreferenceFragment { mUm = (UserManager)getActivity().getSystemService(Context.USER_SERVICE); mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST); mMemStatusPref = mAppListGroup.findPreference(KEY_MEM_STATUS); + mShowSystem = icicle != null ? icicle.getBoolean("show_system") : false; + mUseUss = icicle != null ? icicle.getBoolean("use_uss") : false; + mStatsType = icicle != null ? icicle.getInt("stats_type", MENU_TYPE_BACKGROUND) + : MENU_TYPE_BACKGROUND; setHasOptionsMenu(true); } @@ -113,6 +133,14 @@ public class ProcessStatsUi extends PreferenceFragment { super.onPause(); } + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean("show_system", mShowSystem); + outState.putBoolean("use_uss", mUseUss); + outState.putInt("stats_type", mStatsType); + } + @Override public void onDestroy() { super.onDestroy(); @@ -130,6 +158,7 @@ public class ProcessStatsUi extends PreferenceFragment { ProcessStatsPreference pgp = (ProcessStatsPreference) preference; Bundle args = new Bundle(); args.putParcelable(ProcessStatsDetail.EXTRA_ENTRY, pgp.getEntry()); + args.putBoolean(ProcessStatsDetail.EXTRA_USE_USS, mUseUss); args.putLong(ProcessStatsDetail.EXTRA_MAX_WEIGHT, mMaxWeight); args.putLong(ProcessStatsDetail.EXTRA_TOTAL_TIME, mTotalTime); ((PreferenceActivity) getActivity()).startPreferencePanel( @@ -145,6 +174,31 @@ public class ProcessStatsUi extends PreferenceFragment { .setAlphabeticShortcut('r'); refresh.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + mShowSystemMenu = menu.add(0, MENU_SHOW_SYSTEM, 0, R.string.menu_show_system) + .setAlphabeticShortcut('s') + .setCheckable(true) + .setChecked(mShowSystem) + .setEnabled(mStatsType == MENU_TYPE_BACKGROUND); + mUseUssMenu = menu.add(0, MENU_USE_USS, 0, R.string.menu_use_uss) + .setAlphabeticShortcut('s') + .setCheckable(true) + .setChecked(mUseUss); + SubMenu subMenu = menu.addSubMenu(R.string.menu_proc_stats_type); + mTypeBackgroundMenu = subMenu.add(0, MENU_TYPE_BACKGROUND, 0, + R.string.menu_proc_stats_type_background) + .setAlphabeticShortcut('b') + .setCheckable(true) + .setChecked(mStatsType == MENU_TYPE_BACKGROUND); + mTypeForegroundMenu = subMenu.add(0, MENU_TYPE_FOREGROUND, 0, + R.string.menu_proc_stats_type_foreground) + .setAlphabeticShortcut('f') + .setCheckable(true) + .setChecked(mStatsType == MENU_TYPE_FOREGROUND); + mTypeCachedMenu = subMenu.add(0, MENU_TYPE_CACHED, 0, + R.string.menu_proc_stats_type_cached) + .setAlphabeticShortcut('c') + .setCheckable(true) + .setChecked(mStatsType == MENU_TYPE_CACHED); /* String helpUrl; @@ -162,6 +216,20 @@ public class ProcessStatsUi extends PreferenceFragment { mStats = null; refreshStats(); return true; + case MENU_SHOW_SYSTEM: + mShowSystem = !mShowSystem; + refreshStats(); + return true; + case MENU_USE_USS: + mUseUss = !mUseUss; + refreshStats(); + return true; + case MENU_TYPE_BACKGROUND: + case MENU_TYPE_FOREGROUND: + case MENU_TYPE_CACHED: + mStatsType = item.getItemId(); + refreshStats(); + return true; default: return false; } @@ -173,18 +241,65 @@ public class ProcessStatsUi extends PreferenceFragment { mAppListGroup.addPreference(notAvailable); } + public static final int[] BACKGROUND_AND_SYSTEM_PROC_STATES = new int[] { + ProcessStats.STATE_PERSISTENT, ProcessStats.STATE_IMPORTANT_FOREGROUND, + ProcessStats.STATE_IMPORTANT_BACKGROUND, ProcessStats.STATE_BACKUP, + ProcessStats.STATE_HEAVY_WEIGHT, ProcessStats.STATE_SERVICE, + ProcessStats.STATE_SERVICE_RESTARTING, ProcessStats.STATE_RECEIVER + }; + + public static final int[] FOREGROUND_PROC_STATES = new int[] { + ProcessStats.STATE_TOP + }; + + public static final int[] CACHED_PROC_STATES = new int[] { + ProcessStats.STATE_CACHED_ACTIVITY, ProcessStats.STATE_CACHED_ACTIVITY_CLIENT, + ProcessStats.STATE_CACHED_EMPTY + }; + private void refreshStats() { if (mStats == null) { load(); } + if (mShowSystemMenu != null) { + mShowSystemMenu.setChecked(mShowSystem); + mShowSystemMenu.setEnabled(mStatsType == MENU_TYPE_BACKGROUND); + } + if (mUseUssMenu != null) { + mUseUssMenu.setChecked(mUseUss); + } + if (mTypeBackgroundMenu != null) { + mTypeBackgroundMenu.setChecked(mStatsType == MENU_TYPE_BACKGROUND); + } + if (mTypeForegroundMenu != null) { + mTypeForegroundMenu.setChecked(mStatsType == MENU_TYPE_FOREGROUND); + } + if (mTypeCachedMenu != null) { + mTypeCachedMenu.setChecked(mStatsType == MENU_TYPE_CACHED); + } + + int[] stats; + int statsLabel; + if (mStatsType == MENU_TYPE_FOREGROUND) { + stats = FOREGROUND_PROC_STATES; + statsLabel = R.string.process_stats_type_foreground; + } else if (mStatsType == MENU_TYPE_CACHED) { + stats = CACHED_PROC_STATES; + statsLabel = R.string.process_stats_type_cached; + } else { + stats = mShowSystem ? BACKGROUND_AND_SYSTEM_PROC_STATES + : ProcessStats.BACKGROUND_PROC_STATES; + statsLabel = R.string.process_stats_type_background; + } + mAppListGroup.removeAll(); mAppListGroup.setOrderingAsAdded(false); mMemStatusPref.setOrder(-2); mAppListGroup.addPreference(mMemStatusPref); String durationString = Utils.formatElapsedTime(getActivity(), - mStats.mTimePeriodEndRealtime-mStats.mTimePeriodStartRealtime); + mStats.mTimePeriodEndRealtime-mStats.mTimePeriodStartRealtime, false); CharSequence memString; CharSequence[] memStates = getResources().getTextArray(R.array.ram_states); if (mMemState >= 0 && mMemState < memStates.length) { @@ -193,7 +308,7 @@ public class ProcessStatsUi extends PreferenceFragment { memString = "?"; } mMemStatusPref.setTitle(getActivity().getString(R.string.process_stats_total_duration, - durationString)); + getActivity().getString(statsLabel), durationString)); mMemStatusPref.setSummary(getActivity().getString(R.string.process_stats_memory_status, memString)); /* @@ -208,8 +323,7 @@ public class ProcessStatsUi extends PreferenceFragment { */ ProcessStats.ProcessDataCollection totals = new ProcessStats.ProcessDataCollection( - ProcessStats.ALL_SCREEN_ADJ, ProcessStats.ALL_MEM_ADJ, - ProcessStats.BACKGROUND_PROC_STATES); + ProcessStats.ALL_SCREEN_ADJ, ProcessStats.ALL_MEM_ADJ, stats); long now = SystemClock.uptimeMillis(); @@ -251,7 +365,8 @@ public class ProcessStatsUi extends PreferenceFragment { for (int ip=0, N=mStats.mProcesses.getMap().size(); ip uids = mStats.mProcesses.getMap().valueAt(ip); for (int iu=0; iu uids = mStats.mPackages.getMap().valueAt(ip); - for (int iu=0; iu uids = mStats.mPackages.getMap().valueAt(ip); + for (int iu=0; iu SECONDS_PER_DAY) { @@ -52,15 +56,28 @@ public class Utils { minutes = seconds / SECONDS_PER_MINUTE; seconds -= minutes * SECONDS_PER_MINUTE; } - if (days > 0) { - sb.append(context.getString(R.string.battery_history_days, - days, hours, minutes, seconds)); - } else if (hours > 0) { - sb.append(context.getString(R.string.battery_history_hours, hours, minutes, seconds)); - } else if (minutes > 0) { - sb.append(context.getString(R.string.battery_history_minutes, minutes, seconds)); + if (inclSeconds) { + if (days > 0) { + sb.append(context.getString(R.string.battery_history_days, + days, hours, minutes, seconds)); + } else if (hours > 0) { + sb.append(context.getString(R.string.battery_history_hours, + hours, minutes, seconds)); + } else if (minutes > 0) { + sb.append(context.getString(R.string.battery_history_minutes, minutes, seconds)); + } else { + sb.append(context.getString(R.string.battery_history_seconds, seconds)); + } } else { - sb.append(context.getString(R.string.battery_history_seconds, seconds)); + if (days > 0) { + sb.append(context.getString(R.string.battery_history_days_no_seconds, + days, hours, minutes)); + } else if (hours > 0) { + sb.append(context.getString(R.string.battery_history_hours_no_seconds, + hours, minutes)); + } else { + sb.append(context.getString(R.string.battery_history_minutes_no_seconds, minutes)); + } } return sb.toString(); }