diff --git a/res/layout/manage_applications.xml b/res/layout/manage_applications.xml
index 27164608f3b..078322ace63 100755
--- a/res/layout/manage_applications.xml
+++ b/res/layout/manage_applications.xml
@@ -18,21 +18,62 @@
android:layout_width="match_parent"
android:layout_height="match_parent" >
-
-
-
+
-
+ android:layout_height="match_parent" />
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
-
+ android:paddingTop="30dp"
+ android:paddingLeft="2dp"
+ android:paddingRight="2dp"
+ android:paddingBottom="1dp">
-
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e099bbbb2ad..b28fe4628d9 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1291,7 +1291,7 @@
Total space
- Unmount
+ Unmount SD cardUnmount the internal USB storage so you can format it
@@ -1302,17 +1302,17 @@
Insert an SD card for mounting
- Mount
-
- Mount the internal USB storage
+ Mount SD card
- Mount the SD card
+ Mount the SD card
+
+ Erase USB storage
- Format
+ Erase SD card
- Format (erase) the internal USB storage
+ Erases all data on the phone\'s internal USB storage, such such as music and photos.
- Format (erase) the SD card
+ Erases all data on the phone\'s SD card, such as music and photos.Unavailable
@@ -1421,9 +1421,17 @@
Erases all data on phone
- "This will erase all data from your phone, including:\n
Your Google account
\n
System and application data and settings
\n
Downloaded applications
\nIt will not erase:\n
Current system software and bundled applications
\n
Files in USB storage, such as music or photos: use the Storage settings to format (erase) USB storage
"
+ "This will erase all data from your phone\'s internal storage, including:\n\n
Your Google account
\n
System and application data and settings
\n
Downloaded applications
\n\nTo clear all data on this phone the USB storage needs to be erased.\n\n"
- "This will erase all data from your phone, including:\n
Your Google account
\n
System and application data and settings
\n
Downloaded applications
\nIt will not erase:\n
Current system software and bundled applications
\n
SD card files, such as music or photos: use the Storage settings to format (erase) the SD card
"
+ "This will erase all data from your phone\'s internal storage, including:\n\n
Your Google account
\n
System and application data and settings
\n
Downloaded applications
\n\nTo also clear music, pictures, and other user data, the SD card needs to be erased.\n\n"
+
+ Erase USB storage
+
+ Erase SD card
+
+ Erase all the data on the phone\'s internal USB storage, such as music or photos.
+
+ Erase all the data on the phone\'s SD card, such as music or photos.Reset phone
@@ -1439,21 +1447,21 @@
- Format USB storage
+ Erase USB storage
- Format SD card
+ Erase SD cardErases all data in USB storageErases all data on the SD card
- This action will erase the USB storage. You will lose ALL data in USB storage!
+ This action will erase the USB storage. You will lose all data stored there!
- This action will erase the SD card. You will lose ALL data on the card!
+ This action will erase the SD card. You will lose all data on the card!
- Format USB storage
+ Erase USB storage
- Format SD card
+ Erase SD cardFormat USB storage, erasing all files stored there? Action cannot be reversed!
@@ -1731,6 +1739,10 @@
Sort by nameSort by size
+
+ Show running services
+
+ Show cached processesManage space
@@ -1756,6 +1768,12 @@
DisabledNo applications.
+
+ Internal storage
+
+ USB storage
+
+ SD card storageRecomputing size\u2026
@@ -1831,16 +1849,20 @@ found in the list of installed applications.
View and control currently running servicesRestarting
+
+ Cached background processNothing running.Started by application.%1$s
-
- %1$s available
-
- %1$s in use
+
+ %1$s free
+
+ %1$s used
+
+ RAM%1$s
@@ -1874,6 +1896,10 @@ found in the list of installed applications.
This application can not safely
be stopped. Doing so may lose some of your current work.
+
+ This is an old application
+ process that is being kept for better speed in case it is needed again.
+ There is usually no reason to stop it.%1$s:
currently in use. Touch Settings to control it.
diff --git a/res/xml/device_info_memory.xml b/res/xml/device_info_memory.xml
index 785fded3e6b..fd0bf4e0d62 100644
--- a/res/xml/device_info_memory.xml
+++ b/res/xml/device_info_memory.xml
@@ -16,7 +16,8 @@
-
+ = DisplayMetrics.DENSITY_HIGH
+ ? 2 : 1;
+ mEdgeGradientPaint.setStrokeWidth(mLineWidth);
+ mEdgeGradientPaint.setAntiAlias(true);
+ }
+
+ public void setRatios(float red, float yellow, float green) {
+ mRedRatio = red;
+ mYellowRatio = yellow;
+ mGreenRatio = green;
+ invalidate();
+ }
+
+ public void setShowingGreen(boolean showingGreen) {
+ if (mShowingGreen != showingGreen) {
+ mShowingGreen = showingGreen;
+ updateIndicator();
+ invalidate();
+ }
+ }
+
+ private void updateIndicator() {
+ int off = getPaddingTop() - getPaddingBottom();
+ if (off < 0) off = 0;
+ mRect.top = off;
+ mRect.bottom = getHeight();
+ if (mShowingGreen) {
+ mColorGradientPaint.setShader(new LinearGradient(
+ 0, 0, 0, off-2, RIGHT_COLOR&0xffffff, RIGHT_COLOR, Shader.TileMode.CLAMP));
+ } else {
+ mColorGradientPaint.setShader(new LinearGradient(
+ 0, 0, 0, off-2, MIDDLE_COLOR&0xffffff, MIDDLE_COLOR, Shader.TileMode.CLAMP));
+ }
+ mEdgeGradientPaint.setShader(new LinearGradient(
+ 0, 0, 0, off/2, 0x00a0a0a0, 0xffa0a0a0, Shader.TileMode.CLAMP));
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ updateIndicator();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ int width = getWidth();
+
+ int left = 0;
+
+ int right = left + (int)(width*mRedRatio);
+ int right2 = right + (int)(width*mYellowRatio);
+ int right3 = right2 + (int)(width*mGreenRatio);
+
+ int indicatorLeft, indicatorRight;
+ if (mShowingGreen) {
+ indicatorLeft = right2;
+ indicatorRight = right3;
+ } else {
+ indicatorLeft = right;
+ indicatorRight = right2;
+ }
+
+ if (mLastInterestingLeft != indicatorLeft || mLastInterestingRight != indicatorRight) {
+ mColorPath.reset();
+ mEdgePath.reset();
+ if (indicatorLeft < indicatorRight) {
+ mColorPath.moveTo(indicatorLeft, mRect.top);
+ mColorPath.lineTo(-1, 0);
+ mColorPath.lineTo(width, 0);
+ mColorPath.lineTo(indicatorRight, mRect.top);
+ mColorPath.close();
+ float lineOffset = mLineWidth+.5f;
+ mEdgePath.moveTo(indicatorLeft+lineOffset, mRect.top);
+ mEdgePath.lineTo(-1+lineOffset, 0);
+ mEdgePath.moveTo(indicatorRight-lineOffset, mRect.top);
+ mEdgePath.lineTo(width-lineOffset, 0);
+ }
+ mLastInterestingLeft = indicatorLeft;
+ mLastInterestingRight = indicatorRight;
+ }
+
+ if (!mColorPath.isEmpty()) {
+ canvas.drawPath(mEdgePath, mEdgeGradientPaint);
+ canvas.drawPath(mColorPath, mColorGradientPaint);
+ }
+
+ if (left < right) {
+ mRect.left = left;
+ mRect.right = right;
+ mPaint.setColor(LEFT_COLOR);
+ canvas.drawRect(mRect, mPaint);
+ width -= (right-left);
+ left = right;
+ }
+
+ right = right2;
+
+ if (left < right) {
+ mRect.left = left;
+ mRect.right = right;
+ mPaint.setColor(MIDDLE_COLOR);
+ canvas.drawRect(mRect, mPaint);
+ width -= (right-left);
+ left = right;
+ }
+
+
+ right = left + width;
+ if (left < right) {
+ mRect.left = left;
+ mRect.right = right;
+ mPaint.setColor(RIGHT_COLOR);
+ canvas.drawRect(mRect, mPaint);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index 1053d3bfabe..b4cd26ef790 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -29,9 +29,12 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Environment;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.StatFs;
import android.provider.Settings;
+import android.text.format.Formatter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -126,6 +129,8 @@ public class ManageApplications extends TabActivity implements
public static final int SORT_ORDER_ALPHA = MENU_OPTIONS_BASE + 4;
public static final int SORT_ORDER_SIZE = MENU_OPTIONS_BASE + 5;
+ public static final int SHOW_RUNNING_SERVICES = MENU_OPTIONS_BASE + 6;
+ public static final int SHOW_BACKGROUND_PROCESSES = MENU_OPTIONS_BASE + 7;
// sort order
private int mSortOrder = SORT_ORDER_ALPHA;
// Filter value
@@ -152,6 +157,11 @@ public class ManageApplications extends TabActivity implements
// Custom view used to display running processes
private RunningProcessesView mRunningProcessesView;
+ LinearColorBar mColorBar;
+ TextView mStorageChartLabel;
+ TextView mUsedStorageText;
+ TextView mFreeStorageText;
+
// These are for keeping track of activity and tab switch state.
private int mCurView;
private boolean mCreatedRunning;
@@ -160,6 +170,11 @@ public class ManageApplications extends TabActivity implements
private boolean mActivityResumed;
private Object mNonConfigInstance;
+ private StatFs mDataFileStats;
+ private StatFs mSDCardFileStats;
+ private boolean mLastShowedInternalStorage = true;
+ private long mLastUsedStorage, mLastAppStorage, mLastFreeStorage;
+
final Runnable mRunningProcessesAvail = new Runnable() {
public void run() {
handleRunningProcessesAvail();
@@ -222,6 +237,7 @@ public class ManageApplications extends TabActivity implements
mCurFilterPrefix = constraint;
mEntries = (ArrayList)results.values;
notifyDataSetChanged();
+ updateStorageUsage();
}
};
@@ -294,6 +310,7 @@ public class ManageApplications extends TabActivity implements
mEntries = null;
}
notifyDataSetChanged();
+ updateStorageUsage();
if (entries == null) {
mWaitingForData = true;
@@ -338,6 +355,7 @@ public class ManageApplications extends TabActivity implements
mBaseEntries = apps;
mEntries = applyPrefixFilter(mCurFilterPrefix, mBaseEntries);
notifyDataSetChanged();
+ updateStorageUsage();
}
@Override
@@ -367,6 +385,7 @@ public class ManageApplications extends TabActivity implements
// the list with the new size to reflect it to the user.
rebuild(false);
}
+ updateStorageUsage();
return;
}
}
@@ -502,6 +521,9 @@ public class ManageApplications extends TabActivity implements
mNonConfigInstance = getLastNonConfigurationInstance();
+ mDataFileStats = new StatFs("/data");
+ mSDCardFileStats = new StatFs(Environment.getExternalStorageDirectory().toString());
+
// initialize some window features
requestWindowFeature(Window.FEATURE_RIGHT_ICON);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
@@ -526,6 +548,10 @@ public class ManageApplications extends TabActivity implements
mListView = lv;
lv.setRecyclerListener(mApplicationsAdapter);
mListView.setAdapter(mApplicationsAdapter);
+ mColorBar = (LinearColorBar)mListContainer.findViewById(R.id.storage_color_bar);
+ mStorageChartLabel = (TextView)mListContainer.findViewById(R.id.storageChartLabel);
+ mUsedStorageText = (TextView)mListContainer.findViewById(R.id.usedStorageText);
+ mFreeStorageText = (TextView)mListContainer.findViewById(R.id.freeStorageText);
mRunningProcessesView = (RunningProcessesView)mRootView.findViewById(
R.id.running_processes);
@@ -609,6 +635,8 @@ public class ManageApplications extends TabActivity implements
.setIcon(android.R.drawable.ic_menu_sort_alphabetically);
menu.add(0, SORT_ORDER_SIZE, 2, R.string.sort_order_size)
.setIcon(android.R.drawable.ic_menu_sort_by_size);
+ menu.add(0, SHOW_RUNNING_SERVICES, 3, R.string.show_running_services);
+ menu.add(0, SHOW_BACKGROUND_PROCESSES, 3, R.string.show_background_processes);
return true;
}
@@ -619,11 +647,17 @@ public class ManageApplications extends TabActivity implements
* so bringing up this menu in that case doesn't make any sense.
*/
if (mCurView == VIEW_RUNNING) {
- return false;
+ boolean showingBackground = mRunningProcessesView.mAdapter.getShowBackground();
+ menu.findItem(SORT_ORDER_ALPHA).setVisible(false);
+ menu.findItem(SORT_ORDER_SIZE).setVisible(false);
+ menu.findItem(SHOW_RUNNING_SERVICES).setVisible(showingBackground);
+ menu.findItem(SHOW_BACKGROUND_PROCESSES).setVisible(!showingBackground);
+ } else {
+ menu.findItem(SORT_ORDER_ALPHA).setVisible(mSortOrder != SORT_ORDER_ALPHA);
+ menu.findItem(SORT_ORDER_SIZE).setVisible(mSortOrder != SORT_ORDER_SIZE);
+ menu.findItem(SHOW_RUNNING_SERVICES).setVisible(false);
+ menu.findItem(SHOW_BACKGROUND_PROCESSES).setVisible(false);
}
-
- menu.findItem(SORT_ORDER_ALPHA).setVisible(mSortOrder != SORT_ORDER_ALPHA);
- menu.findItem(SORT_ORDER_SIZE).setVisible(mSortOrder != SORT_ORDER_SIZE);
return true;
}
@@ -632,7 +666,13 @@ public class ManageApplications extends TabActivity implements
int menuId = item.getItemId();
if ((menuId == SORT_ORDER_ALPHA) || (menuId == SORT_ORDER_SIZE)) {
mSortOrder = menuId;
- mApplicationsAdapter.rebuild(mFilterApps, mSortOrder);
+ if (mCurView != VIEW_RUNNING) {
+ mApplicationsAdapter.rebuild(mFilterApps, mSortOrder);
+ }
+ } else if (menuId == SHOW_RUNNING_SERVICES) {
+ mRunningProcessesView.mAdapter.setShowBackground(false);
+ } else if (menuId == SHOW_BACKGROUND_PROCESSES) {
+ mRunningProcessesView.mAdapter.setShowBackground(true);
}
return true;
}
@@ -657,6 +697,82 @@ public class ManageApplications extends TabActivity implements
static final int VIEW_LIST = 1;
static final int VIEW_RUNNING = 2;
+ void updateStorageUsage() {
+ if (mCurView == VIEW_RUNNING) {
+ return;
+ }
+
+ long freeStorage = 0;
+ long appStorage = 0;
+ long totalStorage = 0;
+ CharSequence newLabel = null;
+
+ if (mFilterApps == FILTER_APPS_SDCARD) {
+ if (mLastShowedInternalStorage) {
+ mLastShowedInternalStorage = false;
+ }
+ newLabel = this.getText(R.string.sd_card_storage);
+ mSDCardFileStats.restat(Environment.getExternalStorageDirectory().toString());
+ try {
+ totalStorage = (long)mSDCardFileStats.getBlockCount() *
+ mSDCardFileStats.getBlockSize();
+ freeStorage = (long) mSDCardFileStats.getAvailableBlocks() *
+ mSDCardFileStats.getBlockSize();
+ } catch (IllegalArgumentException e) {
+ // use the old value of mFreeMem
+ }
+ } else {
+ if (!mLastShowedInternalStorage) {
+ mLastShowedInternalStorage = true;
+ }
+ newLabel = this.getText(R.string.internal_storage);
+ mDataFileStats.restat("/data");
+ try {
+ totalStorage = (long)mDataFileStats.getBlockCount() *
+ mDataFileStats.getBlockSize();
+ freeStorage = (long) mDataFileStats.getAvailableBlocks() *
+ mDataFileStats.getBlockSize();
+ } catch (IllegalArgumentException e) {
+ }
+ final int N = mApplicationsAdapter.getCount();
+ for (int i=0; i 0) {
+ mColorBar.setRatios((totalStorage-freeStorage-appStorage)/(float)totalStorage,
+ appStorage/(float)totalStorage, freeStorage/(float)totalStorage);
+ long usedStorage = totalStorage - freeStorage;
+ if (mLastUsedStorage != usedStorage) {
+ mLastUsedStorage = usedStorage;
+ String sizeStr = Formatter.formatShortFileSize(this, usedStorage);
+ mUsedStorageText.setText(getResources().getString(
+ R.string.service_foreground_processes, sizeStr));
+ }
+ if (mLastFreeStorage != freeStorage) {
+ mLastFreeStorage = freeStorage;
+ String sizeStr = Formatter.formatShortFileSize(this, freeStorage);
+ mFreeStorageText.setText(getResources().getString(
+ R.string.service_background_processes, sizeStr));
+ }
+ } else {
+ mColorBar.setRatios(0, 0, 0);
+ if (mLastUsedStorage != -1) {
+ mLastUsedStorage = -1;
+ mUsedStorageText.setText("");
+ }
+ if (mLastFreeStorage != -1) {
+ mLastFreeStorage = -1;
+ mFreeStorageText.setText("");
+ }
+ }
+ }
+
private void selectView(int which) {
if (which == VIEW_LIST) {
if (mResumedRunning) {
@@ -724,6 +840,7 @@ public class ManageApplications extends TabActivity implements
mFilterApps = newOption;
selectView(VIEW_LIST);
+ updateStorageUsage();
}
public void onTabChanged(String tabId) {
diff --git a/src/com/android/settings/applications/RunningProcessesView.java b/src/com/android/settings/applications/RunningProcessesView.java
index 1de67f7a37d..86457bf8b7e 100644
--- a/src/com/android/settings/applications/RunningProcessesView.java
+++ b/src/com/android/settings/applications/RunningProcessesView.java
@@ -22,9 +22,7 @@ import android.app.ActivityManager;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
+import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.SystemProperties;
@@ -39,7 +37,6 @@ import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
-import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AbsListView.RecyclerListener;
@@ -71,6 +68,7 @@ public class RunningProcessesView extends FrameLayout
RunningState.BaseItem mCurSelected;
ListView mListView;
+ ServiceListAdapter mAdapter;
LinearColorBar mColorBar;
TextView mBackgroundProcessText;
TextView mForegroundProcessText;
@@ -93,6 +91,7 @@ public class RunningProcessesView extends FrameLayout
ActivityManager.RunningServiceInfo mService;
ViewHolder mHolder;
long mFirstRunTime;
+ boolean mSetBackground;
void updateTime(Context context, StringBuilder builder) {
TextView uptimeView = null;
@@ -109,14 +108,21 @@ public class RunningProcessesView extends FrameLayout
mHolder.size.setText(size);
}
- if (mItem instanceof RunningState.MergedItem) {
- // This item represents both services and proceses,
+ if (mItem.mBackground) {
+ // This is a background process; no uptime.
+ if (!mSetBackground) {
+ mSetBackground = true;
+ mHolder.uptime.setText("");
+ }
+ } else if (mItem instanceof RunningState.MergedItem) {
+ // This item represents both services and processes,
// so show the service uptime below.
uptimeView = mHolder.uptime;
}
}
if (uptimeView != null) {
+ mSetBackground = false;
if (mFirstRunTime >= 0) {
//Log.i("foo", "Time for " + mItem.mDisplayLabel
// + ": " + (SystemClock.uptimeMillis()-mFirstRunTime));
@@ -159,16 +165,29 @@ public class RunningProcessesView extends FrameLayout
public ActiveItem bind(RunningState state, RunningState.BaseItem item,
StringBuilder builder) {
synchronized (state.mLock) {
+ PackageManager pm = rootView.getContext().getPackageManager();
+ if (item.mPackageInfo == null && item instanceof RunningState.MergedItem) {
+ // Items for background processes don't normally load
+ // their labels for performance reasons. Do it now.
+ ((RunningState.MergedItem)item).mProcess.ensureLabel(pm);
+ item.mPackageInfo = ((RunningState.MergedItem)item).mProcess.mPackageInfo;
+ item.mDisplayLabel = ((RunningState.MergedItem)item).mProcess.mDisplayLabel;
+ }
name.setText(item.mDisplayLabel);
ActiveItem ai = new ActiveItem();
ai.mRootView = rootView;
ai.mItem = item;
ai.mHolder = this;
ai.mFirstRunTime = item.mActiveSince;
- description.setText(item.mDescription);
+ if (item.mBackground) {
+ description.setText(rootView.getContext().getText(R.string.cached));
+ } else {
+ description.setText(item.mDescription);
+ }
item.mCurSizeStr = null;
- icon.setImageDrawable(item.mPackageInfo.loadIcon(
- rootView.getContext().getPackageManager()));
+ if (item.mPackageInfo != null) {
+ icon.setImageDrawable(item.mPackageInfo.loadIcon(pm));
+ }
icon.setVisibility(View.VISIBLE);
ai.updateTime(rootView.getContext(), builder);
return ai;
@@ -185,6 +204,7 @@ public class RunningProcessesView extends FrameLayout
class ServiceListAdapter extends BaseAdapter {
final RunningState mState;
final LayoutInflater mInflater;
+ boolean mShowBackground;
ArrayList mItems;
ServiceListAdapter(RunningState state) {
@@ -194,8 +214,24 @@ public class RunningProcessesView extends FrameLayout
refreshItems();
}
+ void setShowBackground(boolean showBackground) {
+ if (mShowBackground != showBackground) {
+ mShowBackground = showBackground;
+ mState.setWatchingBackgroundItems(showBackground);
+ refreshItems();
+ notifyDataSetChanged();
+ mColorBar.setShowingGreen(mShowBackground);
+ }
+ }
+
+ boolean getShowBackground() {
+ return mShowBackground;
+ }
+
void refreshItems() {
- ArrayList newItems = mState.getCurrentMergedItems();
+ ArrayList newItems =
+ mShowBackground ? mState.getCurrentBackgroundItems()
+ : mState.getCurrentMergedItems();
if (mItems != newItems) {
mItems = newItems;
}
@@ -266,67 +302,6 @@ public class RunningProcessesView extends FrameLayout
}
}
- public static class LinearColorBar extends LinearLayout {
- private float mRedRatio;
- private float mYellowRatio;
- private float mGreenRatio;
-
- final Rect mRect = new Rect();
- final Paint mPaint = new Paint();
-
- public LinearColorBar(Context context, AttributeSet attrs) {
- super(context, attrs);
- setWillNotDraw(false);
- mPaint.setStyle(Paint.Style.FILL);
- }
-
- public void setRatios(float red, float yellow, float green) {
- mRedRatio = red;
- mYellowRatio = yellow;
- mGreenRatio = green;
- invalidate();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- int width = getWidth();
- mRect.top = 0;
- mRect.bottom = getHeight();
-
- int left = 0;
-
- int right = left + (int)(width*mRedRatio);
- if (left < right) {
- mRect.left = left;
- mRect.right = right;
- mPaint.setColor(0xffff8080);
- canvas.drawRect(mRect, mPaint);
- width -= (right-left);
- left = right;
- }
-
- right = left + (int)(width*mYellowRatio);
- if (left < right) {
- mRect.left = left;
- mRect.right = right;
- mPaint.setColor(0xffffff00);
- canvas.drawRect(mRect, mPaint);
- width -= (right-left);
- left = right;
- }
-
- right = left + width;
- if (left < right) {
- mRect.left = left;
- mRect.right = right;
- mPaint.setColor(0xff80ff80);
- canvas.drawRect(mRect, mPaint);
- }
- }
- }
-
private boolean matchText(byte[] buffer, int index, String text) {
int N = text.length();
if ((index+N) >= buffer.length) {
@@ -434,7 +409,7 @@ public class RunningProcessesView extends FrameLayout
+ mLastForegroundProcessMemory + mLastServiceProcessMemory;
mColorBar.setRatios(mLastForegroundProcessMemory/totalMem,
mLastServiceProcessMemory/totalMem,
- (availMem+mLastBackgroundProcessMemory)/totalMem);
+ mLastBackgroundProcessMemory/totalMem);
}
}
@@ -445,6 +420,7 @@ public class RunningProcessesView extends FrameLayout
Intent intent = new Intent();
intent.putExtra(RunningServiceDetails.KEY_UID, mi.mProcess.mUid);
intent.putExtra(RunningServiceDetails.KEY_PROCESS, mi.mProcess.mProcessName);
+ intent.putExtra(RunningServiceDetails.KEY_BACKGROUND, mAdapter.mShowBackground);
intent.setClass(getContext(), RunningServiceDetails.class);
getContext().startActivity(intent);
}
@@ -470,10 +446,23 @@ public class RunningProcessesView extends FrameLayout
}
mListView.setOnItemClickListener(this);
mListView.setRecyclerListener(this);
- mListView.setAdapter(new ServiceListAdapter(mState));
+ mAdapter = new ServiceListAdapter(mState);
+ mListView.setAdapter(mAdapter);
mColorBar = (LinearColorBar)findViewById(R.id.color_bar);
mBackgroundProcessText = (TextView)findViewById(R.id.backgroundText);
+ mBackgroundProcessText.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mAdapter.setShowBackground(true);
+ }
+ });
mForegroundProcessText = (TextView)findViewById(R.id.foregroundText);
+ mForegroundProcessText.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mAdapter.setShowBackground(false);
+ }
+ });
// Magic! Implementation detail! Don't count on this!
SECONDARY_SERVER_MEM =
diff --git a/src/com/android/settings/applications/RunningServiceDetails.java b/src/com/android/settings/applications/RunningServiceDetails.java
index 399c89fe94d..aa89baff5fb 100644
--- a/src/com/android/settings/applications/RunningServiceDetails.java
+++ b/src/com/android/settings/applications/RunningServiceDetails.java
@@ -43,6 +43,7 @@ public class RunningServiceDetails extends Activity
static final String KEY_UID = "uid";
static final String KEY_PROCESS = "process";
+ static final String KEY_BACKGROUND = "background";
static final int DIALOG_CONFIRM_STOP = 1;
@@ -54,6 +55,7 @@ public class RunningServiceDetails extends Activity
int mUid;
String mProcessName;
+ boolean mShowBackground;
RunningState.MergedItem mMergedItem;
@@ -90,9 +92,14 @@ public class RunningServiceDetails extends Activity
}
}
stopService(new Intent().setComponent(si.mRunningService.service));
- if (mMergedItem == null || mMergedItem.mServices.size() <= 1) {
+ if (mMergedItem == null) {
+ // If this is gone, we are gone.
+ mState.updateNow();
+ finish();
+ } else if (!mShowBackground && mMergedItem.mServices.size() <= 1) {
// If there was only one service, we are finishing it,
// so no reason for the UI to stick around.
+ mState.updateNow();
finish();
} else {
mState.updateNow();
@@ -166,6 +173,10 @@ public class RunningServiceDetails extends Activity
}
} else if (mServiceItem != null) {
stopActiveService(false);
+ } else if (mActiveItem.mItem.mBackground) {
+ // Background process. Just kill it.
+ mAm.killBackgroundProcesses(mActiveItem.mItem.mPackageInfo.packageName);
+ finish();
} else {
// Heavy-weight process. We'll do a force-stop on it.
mAm.forceStopPackage(mActiveItem.mItem.mPackageInfo.packageName);
@@ -178,7 +189,8 @@ public class RunningServiceDetails extends Activity
boolean findMergedItem() {
RunningState.MergedItem item = null;
- ArrayList newItems = mState.getCurrentMergedItems();
+ ArrayList newItems = mShowBackground
+ ? mState.getCurrentBackgroundItems() : mState.getCurrentMergedItems();
if (newItems != null) {
for (int i=0; i mHeavyProcesses = new ArrayList();
+ final ArrayList mInterestingProcesses = new ArrayList();
// All currently running processes, for finding dependencies etc.
final SparseArray mRunningProcesses
@@ -109,9 +109,11 @@ public class RunningState {
boolean mResumed;
boolean mHaveData;
+ boolean mWatchingBackgroundItems;
ArrayList mItems = new ArrayList();
ArrayList mMergedItems = new ArrayList();
+ ArrayList mBackgroundItems = new ArrayList();
int mNumBackgroundProcesses;
long mBackgroundProcessMemory;
@@ -207,6 +209,7 @@ public class RunningState {
String mSizeStr;
String mCurSizeStr;
boolean mNeedDivider;
+ boolean mBackground;
public BaseItem(boolean isProcess) {
mIsProcess = isProcess;
@@ -437,26 +440,36 @@ public class RunningState {
final ArrayList mOtherProcesses = new ArrayList();
final ArrayList mServices = new ArrayList();
+ private int mLastNumProcesses = -1, mLastNumServices = -1;
+
MergedItem() {
super(false);
}
- boolean update(Context context) {
+ boolean update(Context context, boolean background) {
mPackageInfo = mProcess.mPackageInfo;
mDisplayLabel = mProcess.mDisplayLabel;
mLabel = mProcess.mLabel;
+ mBackground = background;
- int numProcesses = (mProcess.mPid > 0 ? 1 : 0) + mOtherProcesses.size();
- int numServices = mServices.size();
- int resid = R.string.running_processes_item_description_s_s;
- if (numProcesses != 1) {
- resid = numServices != 1
- ? R.string.running_processes_item_description_p_p
- : R.string.running_processes_item_description_p_s;
- } else if (numServices != 1) {
- resid = R.string.running_processes_item_description_s_p;
+ if (!mBackground) {
+ int numProcesses = (mProcess.mPid > 0 ? 1 : 0) + mOtherProcesses.size();
+ int numServices = mServices.size();
+ if (mLastNumProcesses != numProcesses || mLastNumServices != numServices) {
+ mLastNumProcesses = numProcesses;
+ mLastNumServices = numServices;
+ int resid = R.string.running_processes_item_description_s_s;
+ if (numProcesses != 1) {
+ resid = numServices != 1
+ ? R.string.running_processes_item_description_p_p
+ : R.string.running_processes_item_description_p_s;
+ } else if (numServices != 1) {
+ resid = R.string.running_processes_item_description_s_p;
+ }
+ mDescription = context.getResources().getString(resid, numProcesses,
+ numServices);
+ }
}
- mDescription = context.getResources().getString(resid, numProcesses, numServices);
mActiveSince = -1;
for (int i=0; i newBackgroundItems = null;
try {
final int numProc = mAllProcessItems.size();
int[] pids = new int[numProc];
@@ -908,7 +935,8 @@ public class RunningState {
}
Debug.MemoryInfo[] mem = ActivityManagerNative.getDefault()
.getProcessMemoryInfo(pids);
- for (int i=pids.length-1; i>=0; i--) {
+ int bgIndex = 0;
+ for (int i=0; i=
ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
backgroundProcessMemory += proc.mSize;
+ MergedItem mergedItem;
+ if (newBackgroundItems != null) {
+ mergedItem = proc.mMergedItem = new MergedItem();
+ proc.mMergedItem.mProcess = proc;
+ newBackgroundItems.add(mergedItem);
+ } else {
+ if (bgIndex >= mBackgroundItems.size()
+ || mBackgroundItems.get(bgIndex).mProcess != proc) {
+ newBackgroundItems = new ArrayList(numBackgroundProcesses);
+ for (int bgi=0; bgi numBackgroundProcesses) {
+ newBackgroundItems = new ArrayList(numBackgroundProcesses);
+ for (int bgi=0; bgi getCurrentMergedItems() {
synchronized (mLock) {
return mMergedItems;
}
}
+
+ ArrayList getCurrentBackgroundItems() {
+ synchronized (mLock) {
+ return mBackgroundItems;
+ }
+ }
}
diff --git a/src/com/android/settings/deviceinfo/Memory.java b/src/com/android/settings/deviceinfo/Memory.java
index b57484908cf..0d00528f61b 100644
--- a/src/com/android/settings/deviceinfo/Memory.java
+++ b/src/com/android/settings/deviceinfo/Memory.java
@@ -26,13 +26,9 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.DialogInterface.OnCancelListener;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.os.Bundle;
-import android.os.Handler;
import android.os.IBinder;
-import android.os.Message;
import android.os.RemoteException;
import android.os.Environment;
import android.os.storage.IMountService;
@@ -42,6 +38,7 @@ import android.os.storage.StorageManager;
import android.os.storage.StorageEventListener;
import android.preference.Preference;
import android.preference.PreferenceActivity;
+import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.text.format.Formatter;
import android.util.Log;
@@ -50,9 +47,7 @@ import android.widget.Toast;
import com.android.settings.R;
import java.io.File;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
public class Memory extends PreferenceActivity implements OnCancelListener {
private static final String TAG = "Memory";
@@ -66,6 +61,8 @@ public class Memory extends PreferenceActivity implements OnCancelListener {
private static final String MEMORY_SD_FORMAT = "memory_sd_format";
+ private static final String MEMORY_SD_GROUP = "memory_sd";
+
private static final int DLG_CONFIRM_UNMOUNT = 1;
private static final int DLG_ERROR_UNMOUNT = 2;
@@ -75,6 +72,9 @@ public class Memory extends PreferenceActivity implements OnCancelListener {
private Preference mSdAvail;
private Preference mSdMountToggle;
private Preference mSdFormat;
+ private PreferenceGroup mSdMountPreferenceGroup;
+
+ boolean mSdMountToggleAdded = true;
// Access using getMountService()
private IMountService mMountService = null;
@@ -97,6 +97,8 @@ public class Memory extends PreferenceActivity implements OnCancelListener {
mSdAvail = findPreference(MEMORY_SD_AVAIL);
mSdMountToggle = findPreference(MEMORY_SD_MOUNT_TOGGLE);
mSdFormat = findPreference(MEMORY_SD_FORMAT);
+
+ mSdMountPreferenceGroup = (PreferenceGroup)findPreference(MEMORY_SD_GROUP);
}
@Override
@@ -225,7 +227,6 @@ public class Memory extends PreferenceActivity implements OnCancelListener {
private boolean hasAppsAccessingStorage() throws RemoteException {
String extStoragePath = Environment.getExternalStorageDirectory().toString();
IMountService mountService = getMountService();
- boolean showPidDialog = false;
int stUsers[] = mountService.getStorageUsers(extStoragePath);
if (stUsers != null && stUsers.length > 0) {
return true;
@@ -275,9 +276,15 @@ public class Memory extends PreferenceActivity implements OnCancelListener {
readOnly = mRes.getString(R.string.read_only);
}
- mSdFormat.setEnabled(false);
-
if (status.equals(Environment.MEDIA_MOUNTED)) {
+ if (!Environment.isExternalStorageRemovable()) {
+ // This device has built-in storage that is not removable.
+ // There is no reason for the user to unmount it.
+ if (mSdMountToggleAdded) {
+ mSdMountPreferenceGroup.removePreference(mSdMountToggle);
+ mSdMountToggleAdded = false;
+ }
+ }
try {
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
@@ -303,10 +310,18 @@ public class Memory extends PreferenceActivity implements OnCancelListener {
mSdAvail.setSummary(mRes.getString(R.string.sd_unavailable));
+ if (!Environment.isExternalStorageRemovable()) {
+ if (status.equals(Environment.MEDIA_UNMOUNTED)) {
+ if (!mSdMountToggleAdded) {
+ mSdMountPreferenceGroup.addPreference(mSdMountToggle);
+ mSdMountToggleAdded = true;
+ }
+ }
+ }
+
if (status.equals(Environment.MEDIA_UNMOUNTED) ||
status.equals(Environment.MEDIA_NOFS) ||
status.equals(Environment.MEDIA_UNMOUNTABLE) ) {
- mSdFormat.setEnabled(true);
mSdMountToggle.setEnabled(true);
mSdMountToggle.setTitle(mRes.getString(R.string.sd_mount));
mSdMountToggle.setSummary(mRes.getString(R.string.sd_mount_summary));