Make manage apps UI multi-user aware.
The details screens still need some work. Change-Id: I850cc9ba9a8db7787fae629ae3cb6c6772c726f5
This commit is contained in:
@@ -27,12 +27,16 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageItemInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
@@ -49,6 +53,9 @@ import java.util.List;
|
||||
* applications/processes/services.
|
||||
*/
|
||||
public class RunningState {
|
||||
static final String TAG = "RunningState";
|
||||
static final boolean DEBUG_COMPARE = false;
|
||||
|
||||
static Object sGlobalLock = new Object();
|
||||
static RunningState sInstance;
|
||||
|
||||
@@ -65,6 +72,8 @@ public class RunningState {
|
||||
final Context mApplicationContext;
|
||||
final ActivityManager mAm;
|
||||
final PackageManager mPm;
|
||||
final UserManager mUm;
|
||||
final int mMyUserId;
|
||||
|
||||
OnRefreshUiListener mRefreshUiListener;
|
||||
|
||||
@@ -100,6 +109,17 @@ public class RunningState {
|
||||
// All processes, used for retrieving memory information.
|
||||
final ArrayList<ProcessItem> mAllProcessItems = new ArrayList<ProcessItem>();
|
||||
|
||||
// If there are other users on the device, these are the merged items
|
||||
// representing all items that would be put in mMergedItems for that user.
|
||||
final SparseArray<MergedItem> mOtherUserMergedItems = new SparseArray<MergedItem>();
|
||||
|
||||
// If there are other users on the device, these are the merged items
|
||||
// representing all items that would be put in mUserBackgroundItems for that user.
|
||||
final SparseArray<MergedItem> mOtherUserBackgroundItems = new SparseArray<MergedItem>();
|
||||
|
||||
// Tracking of information about users.
|
||||
final SparseArray<UserState> mUsers = new SparseArray<UserState>();
|
||||
|
||||
static class AppProcessInfo {
|
||||
final ActivityManager.RunningAppProcessInfo info;
|
||||
boolean hasServices;
|
||||
@@ -114,7 +134,64 @@ public class RunningState {
|
||||
final SparseArray<AppProcessInfo> mTmpAppProcesses = new SparseArray<AppProcessInfo>();
|
||||
|
||||
int mSequence = 0;
|
||||
|
||||
|
||||
final Comparator<RunningState.MergedItem> mBackgroundComparator
|
||||
= new Comparator<RunningState.MergedItem>() {
|
||||
@Override
|
||||
public int compare(MergedItem lhs, MergedItem rhs) {
|
||||
if (DEBUG_COMPARE) {
|
||||
Log.i(TAG, "Comparing " + lhs + " with " + rhs);
|
||||
Log.i(TAG, " Proc " + lhs.mProcess + " with " + rhs.mProcess);
|
||||
Log.i(TAG, " UserId " + lhs.mUserId + " with " + rhs.mUserId);
|
||||
}
|
||||
if (lhs.mUserId != rhs.mUserId) {
|
||||
if (lhs.mUserId == mMyUserId) return -1;
|
||||
if (rhs.mUserId == mMyUserId) return 1;
|
||||
return lhs.mUserId < rhs.mUserId ? -1 : 1;
|
||||
}
|
||||
if (lhs.mProcess == rhs.mProcess) {
|
||||
if (lhs.mLabel == rhs.mLabel) {
|
||||
return 0;
|
||||
}
|
||||
return lhs.mLabel != null ? lhs.mLabel.compareTo(rhs.mLabel) : -1;
|
||||
}
|
||||
if (lhs.mProcess == null) return -1;
|
||||
if (rhs.mProcess == null) return 1;
|
||||
if (DEBUG_COMPARE) Log.i(TAG, " Label " + lhs.mProcess.mLabel
|
||||
+ " with " + rhs.mProcess.mLabel);
|
||||
final ActivityManager.RunningAppProcessInfo lhsInfo
|
||||
= lhs.mProcess.mRunningProcessInfo;
|
||||
final ActivityManager.RunningAppProcessInfo rhsInfo
|
||||
= rhs.mProcess.mRunningProcessInfo;
|
||||
final boolean lhsBg = lhsInfo.importance
|
||||
>= ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
|
||||
final boolean rhsBg = rhsInfo.importance
|
||||
>= ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
|
||||
if (DEBUG_COMPARE) Log.i(TAG, " Bg " + lhsBg + " with " + rhsBg);
|
||||
if (lhsBg != rhsBg) {
|
||||
return lhsBg ? 1 : -1;
|
||||
}
|
||||
final boolean lhsA = (lhsInfo.flags
|
||||
& ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES) != 0;
|
||||
final boolean rhsA = (rhsInfo.flags
|
||||
& ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES) != 0;
|
||||
if (DEBUG_COMPARE) Log.i(TAG, " Act " + lhsA + " with " + rhsA);
|
||||
if (lhsA != rhsA) {
|
||||
return lhsA ? -1 : 1;
|
||||
}
|
||||
if (DEBUG_COMPARE) Log.i(TAG, " Lru " + lhsInfo.lru + " with " + rhsInfo.lru);
|
||||
if (lhsInfo.lru != rhsInfo.lru) {
|
||||
return lhsInfo.lru < rhsInfo.lru ? -1 : 1;
|
||||
}
|
||||
if (lhs.mProcess.mLabel == rhs.mProcess.mLabel) {
|
||||
return 0;
|
||||
}
|
||||
if (lhs.mProcess.mLabel == null) return 1;
|
||||
if (rhs.mProcess.mLabel == null) return -1;
|
||||
return lhs.mProcess.mLabel.compareTo(rhs.mProcess.mLabel);
|
||||
}
|
||||
};
|
||||
|
||||
// ----- following protected by mLock -----
|
||||
|
||||
// Lock for protecting the state that will be shared between the
|
||||
@@ -128,6 +205,7 @@ public class RunningState {
|
||||
ArrayList<BaseItem> mItems = new ArrayList<BaseItem>();
|
||||
ArrayList<MergedItem> mMergedItems = new ArrayList<MergedItem>();
|
||||
ArrayList<MergedItem> mBackgroundItems = new ArrayList<MergedItem>();
|
||||
ArrayList<MergedItem> mUserBackgroundItems = new ArrayList<MergedItem>();
|
||||
|
||||
int mNumBackgroundProcesses;
|
||||
long mBackgroundProcessMemory;
|
||||
@@ -211,25 +289,40 @@ public class RunningState {
|
||||
public void onRefreshUi(int what);
|
||||
}
|
||||
|
||||
static class UserState {
|
||||
UserInfo mInfo;
|
||||
String mLabel;
|
||||
Drawable mIcon;
|
||||
}
|
||||
|
||||
static class BaseItem {
|
||||
final boolean mIsProcess;
|
||||
|
||||
final int mUserId;
|
||||
|
||||
PackageItemInfo mPackageInfo;
|
||||
CharSequence mDisplayLabel;
|
||||
String mLabel;
|
||||
String mDescription;
|
||||
|
||||
|
||||
int mCurSeq;
|
||||
|
||||
|
||||
long mActiveSince;
|
||||
long mSize;
|
||||
String mSizeStr;
|
||||
String mCurSizeStr;
|
||||
boolean mNeedDivider;
|
||||
boolean mBackground;
|
||||
|
||||
public BaseItem(boolean isProcess) {
|
||||
|
||||
public BaseItem(boolean isProcess, int userId) {
|
||||
mIsProcess = isProcess;
|
||||
mUserId = userId;
|
||||
}
|
||||
|
||||
public Drawable loadIcon(Context context, RunningState state) {
|
||||
if (mPackageInfo != null) {
|
||||
return mPackageInfo.loadIcon(state.mPm);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,8 +333,8 @@ public class RunningState {
|
||||
|
||||
MergedItem mMergedItem;
|
||||
|
||||
public ServiceItem() {
|
||||
super(false);
|
||||
public ServiceItem(int userId) {
|
||||
super(false, userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,7 +364,7 @@ public class RunningState {
|
||||
long mActiveSince;
|
||||
|
||||
public ProcessItem(Context context, int uid, String processName) {
|
||||
super(true);
|
||||
super(true, UserHandle.getUserId(uid));
|
||||
mDescription = context.getResources().getString(
|
||||
R.string.service_process_name, processName);
|
||||
mUid = uid;
|
||||
@@ -332,8 +425,9 @@ public class RunningState {
|
||||
// If still don't have anything to display, just use the
|
||||
// service info.
|
||||
if (mServices.size() > 0) {
|
||||
mPackageInfo = mServices.values().iterator().next()
|
||||
ApplicationInfo ai = mServices.values().iterator().next()
|
||||
.mServiceInfo.applicationInfo;
|
||||
mPackageInfo = ai;
|
||||
mDisplayLabel = mPackageInfo.loadLabel(pm);
|
||||
mLabel = mDisplayLabel.toString();
|
||||
return;
|
||||
@@ -358,7 +452,7 @@ public class RunningState {
|
||||
ServiceItem si = mServices.get(service.service);
|
||||
if (si == null) {
|
||||
changed = true;
|
||||
si = new ServiceItem();
|
||||
si = new ServiceItem(mUserId);
|
||||
si.mRunningService = service;
|
||||
try {
|
||||
si.mServiceInfo = pm.getServiceInfo(service.service, 0);
|
||||
@@ -456,55 +550,96 @@ public class RunningState {
|
||||
|
||||
static class MergedItem extends BaseItem {
|
||||
ProcessItem mProcess;
|
||||
UserState mUser;
|
||||
final ArrayList<ProcessItem> mOtherProcesses = new ArrayList<ProcessItem>();
|
||||
final ArrayList<ServiceItem> mServices = new ArrayList<ServiceItem>();
|
||||
final ArrayList<MergedItem> mChildren = new ArrayList<MergedItem>();
|
||||
|
||||
private int mLastNumProcesses = -1, mLastNumServices = -1;
|
||||
|
||||
MergedItem() {
|
||||
super(false);
|
||||
MergedItem(int userId) {
|
||||
super(false, userId);
|
||||
}
|
||||
|
||||
|
||||
private void setDescription(Context context, int numProcesses, int numServices) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
boolean update(Context context, boolean background) {
|
||||
mPackageInfo = mProcess.mPackageInfo;
|
||||
mDisplayLabel = mProcess.mDisplayLabel;
|
||||
mLabel = mProcess.mLabel;
|
||||
mBackground = background;
|
||||
|
||||
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;
|
||||
|
||||
if (mUser != null) {
|
||||
// This is a merged item that contains a child collection
|
||||
// of items... that is, it is an entire user, containing
|
||||
// everything associated with that user. So set it up as such.
|
||||
// For concrete stuff we need about the process of this item,
|
||||
// we will just use the info from the first child.
|
||||
MergedItem child0 = mChildren.get(0);
|
||||
mPackageInfo = child0.mProcess.mPackageInfo;
|
||||
mLabel = mUser != null ? mUser.mLabel : null;
|
||||
mDisplayLabel = mLabel;
|
||||
int numProcesses = 0;
|
||||
int numServices = 0;
|
||||
mActiveSince = -1;
|
||||
for (int i=0; i<mChildren.size(); i++) {
|
||||
MergedItem child = mChildren.get(i);
|
||||
numProcesses += child.mLastNumProcesses;
|
||||
numServices += child.mLastNumServices;
|
||||
if (child.mActiveSince >= 0 && mActiveSince < child.mActiveSince) {
|
||||
mActiveSince = child.mActiveSince;
|
||||
}
|
||||
}
|
||||
if (!mBackground) {
|
||||
setDescription(context, numProcesses, numServices);
|
||||
}
|
||||
} else {
|
||||
mPackageInfo = mProcess.mPackageInfo;
|
||||
mDisplayLabel = mProcess.mDisplayLabel;
|
||||
mLabel = mProcess.mLabel;
|
||||
|
||||
if (!mBackground) {
|
||||
setDescription(context, (mProcess.mPid > 0 ? 1 : 0) + mOtherProcesses.size(),
|
||||
mServices.size());
|
||||
}
|
||||
|
||||
mActiveSince = -1;
|
||||
for (int i=0; i<mServices.size(); i++) {
|
||||
ServiceItem si = mServices.get(i);
|
||||
if (si.mActiveSince >= 0 && mActiveSince < si.mActiveSince) {
|
||||
mActiveSince = si.mActiveSince;
|
||||
}
|
||||
mDescription = context.getResources().getString(resid, numProcesses,
|
||||
numServices);
|
||||
}
|
||||
}
|
||||
|
||||
mActiveSince = -1;
|
||||
for (int i=0; i<mServices.size(); i++) {
|
||||
ServiceItem si = mServices.get(i);
|
||||
if (si.mActiveSince >= 0 && mActiveSince < si.mActiveSince) {
|
||||
mActiveSince = si.mActiveSince;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean updateSize(Context context) {
|
||||
mSize = mProcess.mSize;
|
||||
for (int i=0; i<mOtherProcesses.size(); i++) {
|
||||
mSize += mOtherProcesses.get(i).mSize;
|
||||
if (mUser != null) {
|
||||
mSize = 0;
|
||||
for (int i=0; i<mChildren.size(); i++) {
|
||||
MergedItem child = mChildren.get(i);
|
||||
child.updateSize(context);
|
||||
mSize += child.mSize;
|
||||
}
|
||||
} else {
|
||||
mSize = mProcess.mSize;
|
||||
for (int i=0; i<mOtherProcesses.size(); i++) {
|
||||
mSize += mOtherProcesses.get(i).mSize;
|
||||
}
|
||||
}
|
||||
|
||||
String sizeStr = Formatter.formatShortFileSize(
|
||||
@@ -518,10 +653,26 @@ public class RunningState {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Drawable loadIcon(Context context, RunningState state) {
|
||||
if (mUser == null) {
|
||||
return super.loadIcon(context, state);
|
||||
}
|
||||
if (mUser.mIcon != null) {
|
||||
return mUser.mIcon.getConstantState().newDrawable();
|
||||
}
|
||||
return context.getResources().getDrawable(
|
||||
com.android.internal.R.drawable.ic_menu_cc);
|
||||
}
|
||||
}
|
||||
|
||||
static class ServiceProcessComparator implements Comparator<ProcessItem> {
|
||||
|
||||
class ServiceProcessComparator implements Comparator<ProcessItem> {
|
||||
public int compare(ProcessItem object1, ProcessItem object2) {
|
||||
if (object1.mUserId != object2.mUserId) {
|
||||
if (object1.mUserId == mMyUserId) return -1;
|
||||
if (object2.mUserId == mMyUserId) return 1;
|
||||
return object1.mUserId < object2.mUserId ? -1 : 1;
|
||||
}
|
||||
if (object1.mIsStarted != object2.mIsStarted) {
|
||||
// Non-started processes go last.
|
||||
return object1.mIsStarted ? -1 : 1;
|
||||
@@ -570,6 +721,8 @@ public class RunningState {
|
||||
mApplicationContext = context.getApplicationContext();
|
||||
mAm = (ActivityManager)mApplicationContext.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
mPm = mApplicationContext.getPackageManager();
|
||||
mUm = (UserManager)mApplicationContext.getSystemService(Context.USER_SERVICE);
|
||||
mMyUserId = UserHandle.myUserId();
|
||||
mResumed = false;
|
||||
mBackgroundThread = new HandlerThread("RunningState:Background");
|
||||
mBackgroundThread.start();
|
||||
@@ -646,6 +799,42 @@ public class RunningState {
|
||||
mRunningProcesses.clear();
|
||||
mProcessItems.clear();
|
||||
mAllProcessItems.clear();
|
||||
mUsers.clear();
|
||||
}
|
||||
|
||||
private void addOtherUserItem(Context context, ArrayList<MergedItem> newMergedItems,
|
||||
SparseArray<MergedItem> userItems, MergedItem newItem) {
|
||||
MergedItem userItem = userItems.get(newItem.mUserId);
|
||||
boolean first = userItem == null || userItem.mCurSeq != mSequence;
|
||||
if (first) {
|
||||
if (userItem == null) {
|
||||
userItem = new MergedItem(newItem.mUserId);
|
||||
userItems.put(newItem.mUserId, userItem);
|
||||
} else {
|
||||
userItem.mChildren.clear();
|
||||
}
|
||||
userItem.mCurSeq = mSequence;
|
||||
if ((userItem.mUser=mUsers.get(newItem.mUserId)) == null) {
|
||||
userItem.mUser = new UserState();
|
||||
UserInfo info = mUm.getUserInfo(newItem.mUserId);
|
||||
userItem.mUser.mInfo = info;
|
||||
if (info != null && info.iconPath != null) {
|
||||
try {
|
||||
userItem.mUser.mIcon = Drawable.createFromPath(info.iconPath);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Failure loading user picture " + info.iconPath, e);
|
||||
}
|
||||
}
|
||||
String name = info != null ? info.name : null;
|
||||
if (name == null) {
|
||||
name = Integer.toString(info.id);
|
||||
}
|
||||
userItem.mUser.mLabel = context.getResources().getString(
|
||||
R.string.running_process_item_user_label, name);
|
||||
}
|
||||
newMergedItems.add(userItem);
|
||||
}
|
||||
userItem.mChildren.add(newItem);
|
||||
}
|
||||
|
||||
private boolean update(Context context, ActivityManager am) {
|
||||
@@ -940,6 +1129,7 @@ public class RunningState {
|
||||
|
||||
ArrayList<BaseItem> newItems = new ArrayList<BaseItem>();
|
||||
ArrayList<MergedItem> newMergedItems = new ArrayList<MergedItem>();
|
||||
SparseArray<MergedItem> otherUsers = null;
|
||||
mProcessItems.clear();
|
||||
for (int i=0; i<sortedProcesses.size(); i++) {
|
||||
ProcessItem pi = sortedProcesses.get(i);
|
||||
@@ -975,7 +1165,7 @@ public class RunningState {
|
||||
if (!haveAllMerged || mergedItem == null
|
||||
|| mergedItem.mServices.size() != pi.mServices.size()) {
|
||||
// Whoops, we need to build a new MergedItem!
|
||||
mergedItem = new MergedItem();
|
||||
mergedItem = new MergedItem(pi.mUserId);
|
||||
for (ServiceItem si : pi.mServices.values()) {
|
||||
mergedItem.mServices.add(si);
|
||||
si.mMergedItem = mergedItem;
|
||||
@@ -988,9 +1178,13 @@ public class RunningState {
|
||||
}
|
||||
|
||||
mergedItem.update(context, false);
|
||||
newMergedItems.add(mergedItem);
|
||||
if (mergedItem.mUserId != mMyUserId) {
|
||||
addOtherUserItem(context, newMergedItems, mOtherUserMergedItems, mergedItem);
|
||||
} else {
|
||||
newMergedItems.add(mergedItem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Finally, interesting processes need to be shown and will
|
||||
// go at the top.
|
||||
NHP = mInterestingProcesses.size();
|
||||
@@ -998,15 +1192,30 @@ public class RunningState {
|
||||
ProcessItem proc = mInterestingProcesses.get(i);
|
||||
if (proc.mClient == null && proc.mServices.size() <= 0) {
|
||||
if (proc.mMergedItem == null) {
|
||||
proc.mMergedItem = new MergedItem();
|
||||
proc.mMergedItem = new MergedItem(proc.mUserId);
|
||||
proc.mMergedItem.mProcess = proc;
|
||||
}
|
||||
proc.mMergedItem.update(context, false);
|
||||
newMergedItems.add(0, proc.mMergedItem);
|
||||
if (proc.mMergedItem.mUserId != mMyUserId) {
|
||||
addOtherUserItem(context, newMergedItems, mOtherUserMergedItems,
|
||||
proc.mMergedItem);
|
||||
} else {
|
||||
newMergedItems.add(0, proc.mMergedItem);
|
||||
}
|
||||
mProcessItems.add(proc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Finally finally, user aggregated merged items need to be
|
||||
// updated now that they have all of their children.
|
||||
final int NU = mOtherUserMergedItems.size();
|
||||
for (int i=0; i<NU; i++) {
|
||||
MergedItem user = mOtherUserMergedItems.valueAt(i);
|
||||
if (user.mCurSeq == mSequence) {
|
||||
user.update(context, false);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
mItems = newItems;
|
||||
mMergedItems = newMergedItems;
|
||||
@@ -1047,6 +1256,8 @@ public class RunningState {
|
||||
long foregroundProcessMemory = 0;
|
||||
long serviceProcessMemory = 0;
|
||||
ArrayList<MergedItem> newBackgroundItems = null;
|
||||
ArrayList<MergedItem> newUserBackgroundItems = null;
|
||||
boolean diffUsers = false;
|
||||
try {
|
||||
final int numProc = mAllProcessItems.size();
|
||||
int[] pids = new int[numProc];
|
||||
@@ -1066,18 +1277,22 @@ public class RunningState {
|
||||
backgroundProcessMemory += proc.mSize;
|
||||
MergedItem mergedItem;
|
||||
if (newBackgroundItems != null) {
|
||||
mergedItem = proc.mMergedItem = new MergedItem();
|
||||
mergedItem = proc.mMergedItem = new MergedItem(proc.mUserId);
|
||||
proc.mMergedItem.mProcess = proc;
|
||||
diffUsers |= mergedItem.mUserId != mMyUserId;
|
||||
newBackgroundItems.add(mergedItem);
|
||||
} else {
|
||||
if (bgIndex >= mBackgroundItems.size()
|
||||
|| mBackgroundItems.get(bgIndex).mProcess != proc) {
|
||||
newBackgroundItems = new ArrayList<MergedItem>(numBackgroundProcesses);
|
||||
for (int bgi=0; bgi<bgIndex; bgi++) {
|
||||
newBackgroundItems.add(mBackgroundItems.get(bgi));
|
||||
mergedItem = mBackgroundItems.get(bgi);
|
||||
diffUsers |= mergedItem.mUserId != mMyUserId;
|
||||
newBackgroundItems.add(mergedItem);
|
||||
}
|
||||
mergedItem = proc.mMergedItem = new MergedItem();
|
||||
mergedItem = proc.mMergedItem = new MergedItem(proc.mUserId);
|
||||
proc.mMergedItem.mProcess = proc;
|
||||
diffUsers |= mergedItem.mUserId != mMyUserId;
|
||||
newBackgroundItems.add(mergedItem);
|
||||
} else {
|
||||
mergedItem = mBackgroundItems.get(bgIndex);
|
||||
@@ -1099,7 +1314,42 @@ public class RunningState {
|
||||
if (mBackgroundItems.size() > numBackgroundProcesses) {
|
||||
newBackgroundItems = new ArrayList<MergedItem>(numBackgroundProcesses);
|
||||
for (int bgi=0; bgi<numBackgroundProcesses; bgi++) {
|
||||
newBackgroundItems.add(mBackgroundItems.get(bgi));
|
||||
MergedItem mergedItem = mBackgroundItems.get(bgi);
|
||||
diffUsers |= mergedItem.mUserId != mMyUserId;
|
||||
newBackgroundItems.add(mergedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newBackgroundItems != null) {
|
||||
// The background items have changed; we need to re-build the
|
||||
// per-user items.
|
||||
if (!diffUsers) {
|
||||
// Easy: there are no other users, we can just use the same array.
|
||||
newUserBackgroundItems = newBackgroundItems;
|
||||
} else {
|
||||
// We now need to re-build the per-user list so that background
|
||||
// items for users are collapsed together.
|
||||
newUserBackgroundItems = new ArrayList<MergedItem>();
|
||||
final int NB = newBackgroundItems.size();
|
||||
for (int i=0; i<NB; i++) {
|
||||
MergedItem mergedItem = newBackgroundItems.get(i);
|
||||
if (mergedItem.mUserId != mMyUserId) {
|
||||
addOtherUserItem(context, newUserBackgroundItems,
|
||||
mOtherUserBackgroundItems, mergedItem);
|
||||
} else {
|
||||
newUserBackgroundItems.add(mergedItem);
|
||||
}
|
||||
}
|
||||
// And user aggregated merged items need to be
|
||||
// updated now that they have all of their children.
|
||||
final int NU = mOtherUserBackgroundItems.size();
|
||||
for (int i=0; i<NU; i++) {
|
||||
MergedItem user = mOtherUserBackgroundItems.valueAt(i);
|
||||
if (user.mCurSeq == mSequence) {
|
||||
user.update(context, true);
|
||||
user.updateSize(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1117,6 +1367,7 @@ public class RunningState {
|
||||
mServiceProcessMemory = serviceProcessMemory;
|
||||
if (newBackgroundItems != null) {
|
||||
mBackgroundItems = newBackgroundItems;
|
||||
mUserBackgroundItems = newUserBackgroundItems;
|
||||
if (mWatchingBackgroundItems) {
|
||||
changed = true;
|
||||
}
|
||||
@@ -1150,7 +1401,7 @@ public class RunningState {
|
||||
|
||||
ArrayList<MergedItem> getCurrentBackgroundItems() {
|
||||
synchronized (mLock) {
|
||||
return mBackgroundItems;
|
||||
return mUserBackgroundItems;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user