diff --git a/res/layout/preference_linearcolor.xml b/res/layout/preference_linearcolor.xml
new file mode 100644
index 00000000000..bbaf7a1bc89
--- /dev/null
+++ b/res/layout/preference_linearcolor.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 72a6b157e13..44981152342 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1149,4 +1149,16 @@
- Always allow
+
+
+
+ - normal
+
+ - moderate
+
+ - low
+
+ - critical
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b787c8dbe2e..cdf0243166f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3557,7 +3557,10 @@
Memory use
- Over %1$s
+ Stats over %1$s
+
+ Device memory is currently
+ %1$s
diff --git a/src/com/android/settings/applications/LinearColorBar.java b/src/com/android/settings/applications/LinearColorBar.java
index 74fb02e3757..8343595f9e1 100644
--- a/src/com/android/settings/applications/LinearColorBar.java
+++ b/src/com/android/settings/applications/LinearColorBar.java
@@ -23,6 +23,11 @@ public class LinearColorBar extends LinearLayout {
private float mYellowRatio;
private float mGreenRatio;
+ private int mLeftColor = LEFT_COLOR;
+ private int mMiddleColor = MIDDLE_COLOR;
+ private int mRightColor = RIGHT_COLOR;
+
+ private boolean mShowIndicator = true;
private boolean mShowingGreen;
final Rect mRect = new Rect();
@@ -57,6 +62,20 @@ public class LinearColorBar extends LinearLayout {
invalidate();
}
+ public void setColors(int red, int yellow, int green) {
+ mLeftColor = red;
+ mMiddleColor = yellow;
+ mRightColor = green;
+ updateIndicator();
+ invalidate();
+ }
+
+ public void setShowIndicator(boolean showIndicator) {
+ mShowIndicator = showIndicator;
+ updateIndicator();
+ invalidate();
+ }
+
public void setShowingGreen(boolean showingGreen) {
if (mShowingGreen != showingGreen) {
mShowingGreen = showingGreen;
@@ -70,12 +89,15 @@ public class LinearColorBar extends LinearLayout {
if (off < 0) off = 0;
mRect.top = off;
mRect.bottom = getHeight();
+ if (!mShowIndicator) {
+ return;
+ }
if (mShowingGreen) {
mColorGradientPaint.setShader(new LinearGradient(
- 0, 0, 0, off-2, RIGHT_COLOR&0xffffff, RIGHT_COLOR, Shader.TileMode.CLAMP));
+ 0, 0, 0, off-2, mRightColor &0xffffff, mRightColor, Shader.TileMode.CLAMP));
} else {
mColorGradientPaint.setShader(new LinearGradient(
- 0, 0, 0, off-2, MIDDLE_COLOR&0xffffff, MIDDLE_COLOR, Shader.TileMode.CLAMP));
+ 0, 0, 0, off-2, mMiddleColor&0xffffff, mMiddleColor, Shader.TileMode.CLAMP));
}
mEdgeGradientPaint.setShader(new LinearGradient(
0, 0, 0, off/2, 0x00a0a0a0, 0xffa0a0a0, Shader.TileMode.CLAMP));
@@ -111,7 +133,7 @@ public class LinearColorBar extends LinearLayout {
if (mLastInterestingLeft != indicatorLeft || mLastInterestingRight != indicatorRight) {
mColorPath.reset();
mEdgePath.reset();
- if (indicatorLeft < indicatorRight) {
+ if (mShowIndicator && indicatorLeft < indicatorRight) {
final int midTopY = mRect.top;
final int midBottomY = 0;
final int xoff = 2;
@@ -146,7 +168,7 @@ public class LinearColorBar extends LinearLayout {
if (left < right) {
mRect.left = left;
mRect.right = right;
- mPaint.setColor(LEFT_COLOR);
+ mPaint.setColor(mLeftColor);
canvas.drawRect(mRect, mPaint);
width -= (right-left);
left = right;
@@ -157,7 +179,7 @@ public class LinearColorBar extends LinearLayout {
if (left < right) {
mRect.left = left;
mRect.right = right;
- mPaint.setColor(MIDDLE_COLOR);
+ mPaint.setColor(mMiddleColor);
canvas.drawRect(mRect, mPaint);
width -= (right-left);
left = right;
@@ -168,7 +190,7 @@ public class LinearColorBar extends LinearLayout {
if (left < right) {
mRect.left = left;
mRect.right = right;
- mPaint.setColor(RIGHT_COLOR);
+ mPaint.setColor(mRightColor);
canvas.drawRect(mRect, mPaint);
}
}
diff --git a/src/com/android/settings/applications/LinearColorPreference.java b/src/com/android/settings/applications/LinearColorPreference.java
new file mode 100644
index 00000000000..6d9a399ed73
--- /dev/null
+++ b/src/com/android/settings/applications/LinearColorPreference.java
@@ -0,0 +1,51 @@
+/*
+ * 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 android.content.Context;
+import android.preference.Preference;
+import android.view.View;
+import com.android.settings.R;
+
+public class LinearColorPreference extends Preference {
+ float mRedRatio;
+ float mYellowRatio;
+ float mGreenRatio;
+
+ public LinearColorPreference(Context context) {
+ super(context);
+ setLayoutResource(R.layout.preference_linearcolor);
+ }
+
+ public void setRatios(float red, float yellow, float green) {
+ mRedRatio = red;
+ mYellowRatio = yellow;
+ mGreenRatio = green;
+ notifyChanged();
+ }
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+
+ LinearColorBar colors = (LinearColorBar)view.findViewById(
+ R.id.linear_color_bar);
+ colors.setShowIndicator(false);
+ colors.setColors(0xffcc3000, 0xffcccc00, 0xff00cc30);
+ colors.setRatios(mRedRatio, mYellowRatio, mGreenRatio);
+ }
+}
diff --git a/src/com/android/settings/applications/ProcStatsEntry.java b/src/com/android/settings/applications/ProcStatsEntry.java
index dec283f1b73..e1802054f16 100644
--- a/src/com/android/settings/applications/ProcStatsEntry.java
+++ b/src/com/android/settings/applications/ProcStatsEntry.java
@@ -18,7 +18,9 @@ package com.android.settings.applications;
import com.android.internal.app.ProcessStats;
-public class ProcStatsEntry {
+import java.util.ArrayList;
+
+public final class ProcStatsEntry {
final String mPackage;
final int mUid;
final String mName;
@@ -27,7 +29,10 @@ public class ProcStatsEntry {
final long mAvgPss;
final long mWeight;
- ProcStatsEntry(ProcessStats.ProcessState proc, ProcessStats.ProcessDataCollection tmpTotals) {
+ ArrayList mServices;
+
+ public ProcStatsEntry(ProcessStats.ProcessState proc,
+ ProcessStats.ProcessDataCollection tmpTotals) {
ProcessStats.computeProcessData(proc, tmpTotals, 0);
mPackage = proc.mPackage;
mUid = proc.mUid;
@@ -37,4 +42,35 @@ public class ProcStatsEntry {
mAvgPss = tmpTotals.avgPss;
mWeight = mDuration * mAvgPss;
}
+
+ public void addServices(ProcessStats.PackageState pkgState) {
+ for (int isvc=0, NSVC=pkgState.mServices.size(); isvc();
+ }
+ mServices.add(new Service(svc));
+ }
+ }
+
+ public static final class Service {
+ final String mPackage;
+ final String mName;
+ final long mDuration;
+
+ public Service(ProcessStats.ServiceState service) {
+ mPackage = service.mPackage;
+ mName = service.mName;
+ mDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
+ ProcessStats.ServiceState.SERVICE_STARTED,
+ ProcessStats.STATE_NOTHING, 0, 0)
+ + ProcessStats.dumpSingleServiceTime(null, null, service,
+ ProcessStats.ServiceState.SERVICE_BOUND,
+ ProcessStats.STATE_NOTHING, 0, 0)
+ + ProcessStats.dumpSingleServiceTime(null, null, service,
+ ProcessStats.ServiceState.SERVICE_EXEC,
+ ProcessStats.STATE_NOTHING, 0, 0);
+ }
+ }
}
diff --git a/src/com/android/settings/applications/ProcessStatsUi.java b/src/com/android/settings/applications/ProcessStatsUi.java
index 3632288a27f..ec49e0d5149 100644
--- a/src/com/android/settings/applications/ProcessStatsUi.java
+++ b/src/com/android/settings/applications/ProcessStatsUi.java
@@ -33,6 +33,7 @@ import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.text.format.DateFormat;
import android.util.Log;
+import android.util.SparseArray;
import android.util.TimeUtils;
import android.view.Menu;
import android.view.MenuInflater;
@@ -60,11 +61,24 @@ public class ProcessStatsUi extends PreferenceFragment {
static final int MAX_ITEMS_TO_LIST = 20;
+ final static Comparator sEntryCompare = new Comparator() {
+ @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;
+ }
+ };
+
private static ProcessStats sStatsXfer;
IProcessStats mProcessStats;
UserManager mUm;
ProcessStats mStats;
+ int mMemState;
private PreferenceGroup mAppListGroup;
private Preference mMemStatusPref;
@@ -169,8 +183,17 @@ public class ProcessStatsUi extends PreferenceFragment {
mAppListGroup.addPreference(mMemStatusPref);
String durationString = Utils.formatElapsedTime(getActivity(),
mStats.mTimePeriodEndRealtime-mStats.mTimePeriodStartRealtime);
+ CharSequence memString;
+ CharSequence[] memStates = getResources().getTextArray(R.array.ram_states);
+ if (mMemState >= 0 && mMemState < memStates.length) {
+ memString = memStates[mMemState];
+ } else {
+ memString = "?";
+ }
mMemStatusPref.setTitle(getActivity().getString(R.string.process_stats_total_duration,
durationString));
+ mMemStatusPref.setSummary(getActivity().getString(R.string.process_stats_memory_status,
+ memString));
/*
mMemStatusPref.setTitle(DateFormat.format(DateFormat.getBestDateTimePattern(
getActivity().getResources().getConfiguration().locale,
@@ -188,30 +211,47 @@ public class ProcessStatsUi extends PreferenceFragment {
long now = SystemClock.uptimeMillis();
+ final PackageManager pm = getActivity().getPackageManager();
+
mTotalTime = ProcessStats.dumpSingleTime(null, null, mStats.mMemFactorDurations,
mStats.mMemFactor, mStats.mStartTime, now);
+ LinearColorPreference colors = new LinearColorPreference(getActivity());
+ colors.setOrder(-1);
+ mAppListGroup.addPreference(colors);
+
+ long[] memTimes = new long[ProcessStats.ADJ_MEM_FACTOR_COUNT];
+ for (int iscreen=0; iscreen procs = new ArrayList();
+
+ /*
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;
+ */
+
+ for (int ip=0, N=mStats.mProcesses.getMap().size(); ip uids = mStats.mProcesses.getMap().valueAt(ip);
+ for (int iu=0; iu MAX_ITEMS_TO_LIST) {
procs.remove(procs.size()-1);
}
@@ -232,19 +272,56 @@ public class ProcessStatsUi extends PreferenceFragment {
ProcessStatsPreference pref = new ProcessStatsPreference(getActivity(), null);
ApplicationInfo targetApp = null;
String label = proc.mName;
+ String pkgName = null;
if (proc.mUnique) {
+ pkgName = proc.mPackage;
+ proc.addServices(mStats.getPackageStateLocked(proc.mPackage, proc.mUid));
+ } else {
+ // See if there is one significant package that was running here.
+ ArrayList subProcs = new ArrayList();
+ for (int ipkg=0, NPKG=mStats.mPackages.getMap().size(); ipkg uids
+ = mStats.mPackages.getMap().valueAt(ipkg);
+ for (int iu=0, NU=uids.size(); iu 1) {
+ Collections.sort(subProcs, sEntryCompare);
+ if (subProcs.get(0).mWeight > (subProcs.get(1).mWeight*3)) {
+ pkgName = subProcs.get(0).mPackage;
+ }
+ }
+ }
+ if (pkgName != null) {
// Only one app associated with this process.
try {
- targetApp = pm.getApplicationInfo(proc.mPackage,
+ targetApp = pm.getApplicationInfo(pkgName,
PackageManager.GET_DISABLED_COMPONENTS |
PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
PackageManager.GET_UNINSTALLED_PACKAGES);
String name = targetApp.loadLabel(pm).toString();
- if (proc.mName.equals(proc.mPackage)) {
+ if (proc.mName.equals(pkgName)) {
label = name;
} else {
- if (proc.mName.startsWith(proc.mPackage)) {
- int off = proc.mPackage.length();
+ if (proc.mName.startsWith(pkgName)) {
+ int off = pkgName.length();
if (proc.mName.length() > off) {
off++;
}
@@ -258,15 +335,15 @@ public class ProcessStatsUi extends PreferenceFragment {
}
if (targetApp == null) {
String[] packages = pm.getPackagesForUid(proc.mUid);
- for (String pkgName : packages) {
+ for (String curPkg : packages) {
try {
- final PackageInfo pi = pm.getPackageInfo(pkgName,
+ final PackageInfo pi = pm.getPackageInfo(curPkg,
PackageManager.GET_DISABLED_COMPONENTS |
PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
PackageManager.GET_UNINSTALLED_PACKAGES);
if (pi.sharedUserLabel != 0) {
targetApp = pi.applicationInfo;
- final CharSequence nm = pm.getText(pkgName,
+ final CharSequence nm = pm.getText(curPkg,
pi.sharedUserLabel, pi.applicationInfo);
if (nm != null) {
label = nm.toString() + " (" + proc.mName + ")";
@@ -293,6 +370,7 @@ public class ProcessStatsUi extends PreferenceFragment {
private void load() {
try {
+ mMemState = mProcessStats.getCurrentMemoryState();
ArrayList fds = new ArrayList();
byte[] data = mProcessStats.getCurrentStats(fds);
Parcel parcel = Parcel.obtain();
@@ -300,7 +378,7 @@ public class ProcessStatsUi extends PreferenceFragment {
parcel.setDataPosition(0);
mStats = ProcessStats.CREATOR.createFromParcel(parcel);
int i = fds.size()-1;
- while (i > 0 && (mStats.mTimePeriodEndRealtime-mStats.mTimePeriodStartRealtime)
+ while (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);