diff options
author | Dianne Hackborn <hackbod@google.com> | 2010-03-30 18:25:10 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-03-30 18:25:10 -0700 |
commit | d4fb738aa721f5bd16e5fa71bb3bbbe14d85a450 (patch) | |
tree | 09dfe0f0bcbf777af01a1d456f453154a701b093 /src/com | |
parent | 388b4a8726459c20827bc44488ffb9eb890080ee (diff) | |
parent | 309f2362559e35faa1ff62f2c3ee3948dbb9fa49 (diff) | |
download | packages_apps_settings-d4fb738aa721f5bd16e5fa71bb3bbbe14d85a450.zip packages_apps_settings-d4fb738aa721f5bd16e5fa71bb3bbbe14d85a450.tar.gz packages_apps_settings-d4fb738aa721f5bd16e5fa71bb3bbbe14d85a450.tar.bz2 |
Merge "Fix issue# 2544176: running services list update outside of ui thread." into froyo
Diffstat (limited to 'src/com')
-rw-r--r-- | src/com/android/settings/RunningServices.java | 130 |
1 files changed, 98 insertions, 32 deletions
diff --git a/src/com/android/settings/RunningServices.java b/src/com/android/settings/RunningServices.java index 669ec98..e67adf0 100644 --- a/src/com/android/settings/RunningServices.java +++ b/src/com/android/settings/RunningServices.java @@ -64,6 +64,8 @@ import android.widget.TextView; import java.io.FileInputStream; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -189,6 +191,11 @@ public class RunningServices extends ListActivity int mRunningSeq; ActivityManager.RunningAppProcessInfo mRunningProcessInfo; + // Purely for sorting. + boolean mIsSystem; + boolean mIsStarted; + long mActiveSince; + public ProcessItem(Context context, int uid, String processName) { super(true); mDescription = context.getResources().getString( @@ -382,11 +389,32 @@ public class RunningServices extends ListActivity } } + static class ServiceProcessComparator implements Comparator<ProcessItem> { + public int compare(ProcessItem object1, ProcessItem object2) { + if (object1.mIsStarted != object2.mIsStarted) { + // Non-started processes go last. + return object1.mIsStarted ? -1 : 1; + } + if (object1.mIsSystem != object2.mIsSystem) { + // System processes go below non-system. + return object1.mIsSystem ? 1 : -1; + } + if (object1.mActiveSince != object2.mActiveSince) { + // Remaining ones are sorted with the longest running + // services last. + return (object1.mActiveSince > object2.mActiveSince) ? -1 : 1; + } + return 0; + } + } + static class State { final SparseArray<HashMap<String, ProcessItem>> mProcesses = new SparseArray<HashMap<String, ProcessItem>>(); final SparseArray<ProcessItem> mActiveProcesses = new SparseArray<ProcessItem>(); + final ServiceProcessComparator mServiceProcessComparator + = new ServiceProcessComparator(); // Temporary for finding process dependencies. final SparseArray<ProcessItem> mRunningProcesses @@ -566,25 +594,51 @@ public class RunningServices extends ListActivity } if (changed) { - ArrayList<BaseItem> newItems = new ArrayList<BaseItem>(); - mProcessItems.clear(); + // First determine an order for the services. + ArrayList<ProcessItem> sortedProcesses = new ArrayList<ProcessItem>(); for (int i=0; i<mProcesses.size(); i++) { for (ProcessItem pi : mProcesses.valueAt(i).values()) { - pi.mNeedDivider = false; - // First add processes we are dependent on. - pi.addDependentProcesses(newItems, mProcessItems); - // And add the process itself. - newItems.add(pi); - if (pi.mPid > 0) { - mProcessItems.add(pi); - } - // And finally the services running in it. - boolean needDivider = false; + pi.mIsSystem = false; + pi.mIsStarted = true; + pi.mActiveSince = Long.MAX_VALUE; for (ServiceItem si : pi.mServices.values()) { - si.mNeedDivider = needDivider; - needDivider = true; - newItems.add(si); + if (si.mServiceInfo != null + && (si.mServiceInfo.applicationInfo.flags + & ApplicationInfo.FLAG_SYSTEM) != 0) { + pi.mIsSystem = true; + } + if (si.mRunningService != null + && si.mRunningService.clientLabel != 0) { + pi.mIsStarted = false; + if (pi.mActiveSince > si.mRunningService.activeSince) { + pi.mActiveSince = si.mRunningService.activeSince; + } + } } + sortedProcesses.add(pi); + } + } + + Collections.sort(sortedProcesses, mServiceProcessComparator); + + ArrayList<BaseItem> newItems = new ArrayList<BaseItem>(); + mProcessItems.clear(); + for (int i=0; i<sortedProcesses.size(); i++) { + ProcessItem pi = sortedProcesses.get(i); + pi.mNeedDivider = false; + // First add processes we are dependent on. + pi.addDependentProcesses(newItems, mProcessItems); + // And add the process itself. + newItems.add(pi); + if (pi.mPid > 0) { + mProcessItems.add(pi); + } + // And finally the services running in it. + boolean needDivider = false; + for (ServiceItem si : pi.mServices.values()) { + si.mNeedDivider = needDivider; + needDivider = true; + newItems.add(si); } } synchronized (mLock) { @@ -660,6 +714,12 @@ public class RunningServices extends ListActivity return changed; } + + ArrayList<BaseItem> getCurrentItems() { + synchronized (mLock) { + return mItems; + } + } } static class TimeTicker extends TextView { @@ -679,32 +739,38 @@ public class RunningServices extends ListActivity class ServiceListAdapter extends BaseAdapter { final State mState; final LayoutInflater mInflater; + ArrayList<BaseItem> mItems; ServiceListAdapter(State state) { - synchronized (state.mLock) { - mState = state; - mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); - } + mState = state; + mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); + refreshItems(); } + void refreshItems() { + ArrayList<BaseItem> newItems = mState.getCurrentItems(); + if (mItems != newItems) { + mItems = newItems; + } + if (mItems == null) { + mItems = new ArrayList<BaseItem>(); + } + } + public boolean hasStableIds() { return true; } public int getCount() { - synchronized (mState.mLock) { - return mState.mItems.size(); - } + return mItems.size(); } public Object getItem(int position) { - synchronized (mState.mLock) { - return mState.mItems.get(position); - } + return mItems.get(position); } public long getItemId(int position) { - return position; + return mItems.get(position).hashCode(); } public boolean areAllItemsEnabled() { @@ -712,9 +778,7 @@ public class RunningServices extends ListActivity } public boolean isEnabled(int position) { - synchronized (mState.mLock) { - return !mState.mItems.get(position).mIsProcess; - } + return !mItems.get(position).mIsProcess; } public View getView(int position, View convertView, ViewGroup parent) { @@ -743,13 +807,13 @@ public class RunningServices extends ListActivity public void bindView(View view, int position) { synchronized (mState.mLock) { ViewHolder vh = (ViewHolder) view.getTag(); - if (position >= mState.mItems.size()) { + if (position >= mItems.size()) { // List must have changed since we last reported its // size... ignore here, we will be doing a data changed // to refresh the entire list. return; } - BaseItem item = mState.mItems.get(position); + BaseItem item = mItems.get(position); vh.name.setText(item.mDisplayLabel); vh.separator.setVisibility(item.mNeedDivider ? View.VISIBLE : View.INVISIBLE); @@ -967,7 +1031,9 @@ public class RunningServices extends ListActivity void refreshUi(boolean dataChanged) { if (dataChanged) { - ((ServiceListAdapter)(getListView().getAdapter())).notifyDataSetChanged(); + ServiceListAdapter adapter = (ServiceListAdapter)(getListView().getAdapter()); + adapter.refreshItems(); + adapter.notifyDataSetChanged(); } // This is the amount of available memory until we start killing |