1728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn/*
2728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn * Copyright (C) 2010 The Android Open Source Project
3728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn *
4728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn * you may not use this file except in compliance with the License.
6728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn * You may obtain a copy of the License at
7728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn *
8728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn *
10728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
11728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn * See the License for the specific language governing permissions and
14728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn * limitations under the License.
15728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn */
16728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
17728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornpackage com.android.settings.applications;
18728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
19728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport com.android.settings.R;
2095b86a5488a27d95bda8b6db1f608d6ce55dae8aAlexandra Gherghinaimport com.android.settings.Utils;
21728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
22728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.app.ActivityManager;
23728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.app.ActivityManagerNative;
240e092f4eb010976349e3fd1e49e41e14b1a33aaaJeff Sharkeyimport android.app.ActivityThread;
25728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.content.ComponentName;
26728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.content.Context;
27728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.content.pm.ApplicationInfo;
28728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.content.pm.PackageInfo;
29728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.content.pm.PackageItemInfo;
30728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.content.pm.PackageManager;
31728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.content.pm.ServiceInfo;
32271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackbornimport android.content.pm.UserInfo;
33728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.content.res.Resources;
34271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackbornimport android.graphics.drawable.Drawable;
35b0b0b110c04ddbbe5e2651dcb1a6f13551c61fb8Amith Yamasaniimport android.graphics.drawable.Drawable.ConstantState;
36508fedc4102790dcd7004e4962e2b540967b714bDianne Hackbornimport android.os.Handler;
37508fedc4102790dcd7004e4962e2b540967b714bDianne Hackbornimport android.os.HandlerThread;
38508fedc4102790dcd7004e4962e2b540967b714bDianne Hackbornimport android.os.Looper;
39508fedc4102790dcd7004e4962e2b540967b714bDianne Hackbornimport android.os.Message;
40728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.os.RemoteException;
41271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackbornimport android.os.UserHandle;
42271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackbornimport android.os.UserManager;
43728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.text.format.Formatter;
44728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.util.Log;
45728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport android.util.SparseArray;
46728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
47728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport java.util.ArrayList;
48728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport java.util.Collections;
49728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport java.util.Comparator;
50728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport java.util.HashMap;
51728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport java.util.Iterator;
52728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornimport java.util.List;
53728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
54728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn/**
55728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn * Singleton for retrieving and monitoring the state about all running
56728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn * applications/processes/services.
57728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn */
58728ac35373028b79205a788c526ef4b495518ec1Dianne Hackbornpublic class RunningState {
59271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    static final String TAG = "RunningState";
60271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    static final boolean DEBUG_COMPARE = false;
61271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
62508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    static Object sGlobalLock = new Object();
63508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    static RunningState sInstance;
64508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
652372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn    static final int MSG_RESET_CONTENTS = 1;
662372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn    static final int MSG_UPDATE_CONTENTS = 2;
672372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn    static final int MSG_REFRESH_UI = 3;
682372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn    static final int MSG_UPDATE_TIME = 4;
69508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
70508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    static final long TIME_UPDATE_DELAY = 1000;
71508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    static final long CONTENTS_UPDATE_DELAY = 2000;
72508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
73508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    static final int MAX_SERVICES = 100;
74508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
75508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    final Context mApplicationContext;
76508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    final ActivityManager mAm;
77508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    final PackageManager mPm;
78271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    final UserManager mUm;
79271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    final int mMyUserId;
80508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
81508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    OnRefreshUiListener mRefreshUiListener;
82728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
832372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn    final InterestingConfigChanges mInterestingConfigChanges = new InterestingConfigChanges();
842372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn
85c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    // Processes that are hosting a service we are interested in, organized
86c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    // by uid and name.  Note that this mapping does not change even across
87c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    // service restarts, and during a restart there will still be a process
88c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    // entry.
89c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    final SparseArray<HashMap<String, ProcessItem>> mServiceProcessesByName
90728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            = new SparseArray<HashMap<String, ProcessItem>>();
91c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn
92c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    // Processes that are hosting a service we are interested in, organized
93c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    // by their pid.  These disappear and re-appear as services are restarted.
94c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    final SparseArray<ProcessItem> mServiceProcessesByPid
95728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            = new SparseArray<ProcessItem>();
96c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn
97c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    // Used to sort the interesting processes.
98728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    final ServiceProcessComparator mServiceProcessComparator
99728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            = new ServiceProcessComparator();
100728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
1011337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn    // Additional interesting processes to be shown to the user, even if
102c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    // there is no service running in them.
1031337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn    final ArrayList<ProcessItem> mInterestingProcesses = new ArrayList<ProcessItem>();
104c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn
105c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    // All currently running processes, for finding dependencies etc.
106728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    final SparseArray<ProcessItem> mRunningProcesses
107728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            = new SparseArray<ProcessItem>();
108728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
109c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    // The processes associated with services, in sorted order.
110728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    final ArrayList<ProcessItem> mProcessItems = new ArrayList<ProcessItem>();
111c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn
112c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn    // All processes, used for retrieving memory information.
113728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    final ArrayList<ProcessItem> mAllProcessItems = new ArrayList<ProcessItem>();
1144bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn
115271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    // If there are other users on the device, these are the merged items
116271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    // representing all items that would be put in mMergedItems for that user.
117271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    final SparseArray<MergedItem> mOtherUserMergedItems = new SparseArray<MergedItem>();
118271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
119271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    // If there are other users on the device, these are the merged items
120271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    // representing all items that would be put in mUserBackgroundItems for that user.
121271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    final SparseArray<MergedItem> mOtherUserBackgroundItems = new SparseArray<MergedItem>();
122271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
123271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    // Tracking of information about users.
124271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    final SparseArray<UserState> mUsers = new SparseArray<UserState>();
125271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
1264bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn    static class AppProcessInfo {
1274bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        final ActivityManager.RunningAppProcessInfo info;
1284bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        boolean hasServices;
1294bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        boolean hasForegroundServices;
1304bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn
1314bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        AppProcessInfo(ActivityManager.RunningAppProcessInfo _info) {
1324bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            info = _info;
1334bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        }
1344bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn    }
1354bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn
1364bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn    // Temporary structure used when updating above information.
1374bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn    final SparseArray<AppProcessInfo> mTmpAppProcesses = new SparseArray<AppProcessInfo>();
1384bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn
139728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    int mSequence = 0;
140271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
141271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    final Comparator<RunningState.MergedItem> mBackgroundComparator
142271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        = new Comparator<RunningState.MergedItem>() {
143271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            @Override
144271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            public int compare(MergedItem lhs, MergedItem rhs) {
145271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (DEBUG_COMPARE) {
146271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    Log.i(TAG, "Comparing " + lhs + " with " + rhs);
147271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    Log.i(TAG, "     Proc " + lhs.mProcess + " with " + rhs.mProcess);
148271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    Log.i(TAG, "   UserId " + lhs.mUserId + " with " + rhs.mUserId);
149271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
150271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (lhs.mUserId != rhs.mUserId) {
151271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    if (lhs.mUserId == mMyUserId) return -1;
152271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    if (rhs.mUserId == mMyUserId) return 1;
153271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    return lhs.mUserId < rhs.mUserId ? -1 : 1;
154271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
155271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (lhs.mProcess == rhs.mProcess) {
156271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    if (lhs.mLabel == rhs.mLabel) {
157271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        return 0;
158271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    }
159271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    return lhs.mLabel != null ? lhs.mLabel.compareTo(rhs.mLabel) : -1;
160271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
161271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (lhs.mProcess == null) return -1;
162271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (rhs.mProcess == null) return 1;
163271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (DEBUG_COMPARE) Log.i(TAG, "    Label " + lhs.mProcess.mLabel
164271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        + " with " + rhs.mProcess.mLabel);
165271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                final ActivityManager.RunningAppProcessInfo lhsInfo
166271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        = lhs.mProcess.mRunningProcessInfo;
167271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                final ActivityManager.RunningAppProcessInfo rhsInfo
168271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        = rhs.mProcess.mRunningProcessInfo;
169271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                final boolean lhsBg = lhsInfo.importance
170271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        >= ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
171271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                final boolean rhsBg = rhsInfo.importance
172271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        >= ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
173271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        if (DEBUG_COMPARE) Log.i(TAG, "       Bg " + lhsBg + " with " + rhsBg);
174271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (lhsBg != rhsBg) {
175271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    return lhsBg ? 1 : -1;
176271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
177271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                final boolean lhsA = (lhsInfo.flags
178271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        & ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES) != 0;
179271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                final boolean rhsA = (rhsInfo.flags
180271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        & ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES) != 0;
181271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (DEBUG_COMPARE) Log.i(TAG, "      Act " + lhsA + " with " + rhsA);
182271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (lhsA != rhsA) {
183271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    return lhsA ? -1 : 1;
184271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
185271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (DEBUG_COMPARE) Log.i(TAG, "      Lru " + lhsInfo.lru + " with " + rhsInfo.lru);
186271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (lhsInfo.lru != rhsInfo.lru) {
187271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    return lhsInfo.lru < rhsInfo.lru ? -1 : 1;
188271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
189271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (lhs.mProcess.mLabel == rhs.mProcess.mLabel) {
190271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    return 0;
191271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
192271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (lhs.mProcess.mLabel == null) return 1;
193271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (rhs.mProcess.mLabel == null) return -1;
194271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                return lhs.mProcess.mLabel.compareTo(rhs.mProcess.mLabel);
195271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            }
196271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    };
197271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
198728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    // ----- following protected by mLock -----
199728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
200728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    // Lock for protecting the state that will be shared between the
201728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    // background update thread and the UI thread.
202728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    final Object mLock = new Object();
203728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
204508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    boolean mResumed;
205508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    boolean mHaveData;
2061337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn    boolean mWatchingBackgroundItems;
207508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
208728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    ArrayList<BaseItem> mItems = new ArrayList<BaseItem>();
209728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    ArrayList<MergedItem> mMergedItems = new ArrayList<MergedItem>();
2101337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn    ArrayList<MergedItem> mBackgroundItems = new ArrayList<MergedItem>();
211271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    ArrayList<MergedItem> mUserBackgroundItems = new ArrayList<MergedItem>();
212728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
213728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    int mNumBackgroundProcesses;
214728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    long mBackgroundProcessMemory;
215728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    int mNumForegroundProcesses;
216728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    long mForegroundProcessMemory;
217728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    int mNumServiceProcesses;
218728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    long mServiceProcessMemory;
219728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
220508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    // ----- BACKGROUND MONITORING THREAD -----
221508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
222508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    final HandlerThread mBackgroundThread;
223508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    final class BackgroundHandler extends Handler {
224508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        public BackgroundHandler(Looper looper) {
225508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            super(looper);
226508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        }
227508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
228508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        @Override
229508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        public void handleMessage(Message msg) {
230508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            switch (msg.what) {
2312372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn                case MSG_RESET_CONTENTS:
2322372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn                    reset();
2332372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn                    break;
234508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                case MSG_UPDATE_CONTENTS:
235508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    synchronized (mLock) {
236508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                        if (!mResumed) {
237508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                            return;
238508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                        }
239508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    }
240508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    Message cmd = mHandler.obtainMessage(MSG_REFRESH_UI);
241508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    cmd.arg1 = update(mApplicationContext, mAm) ? 1 : 0;
242508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    mHandler.sendMessage(cmd);
243508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    removeMessages(MSG_UPDATE_CONTENTS);
244508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    msg = obtainMessage(MSG_UPDATE_CONTENTS);
245508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    sendMessageDelayed(msg, CONTENTS_UPDATE_DELAY);
246508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    break;
247508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            }
248508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        }
249508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    };
250508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
251508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    final BackgroundHandler mBackgroundHandler;
252508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
253508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    final Handler mHandler = new Handler() {
254508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        int mNextUpdate = OnRefreshUiListener.REFRESH_TIME;
255508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
256508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        @Override
257508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        public void handleMessage(Message msg) {
258508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            switch (msg.what) {
259508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                case MSG_REFRESH_UI:
260508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    mNextUpdate = msg.arg1 != 0
261508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                            ? OnRefreshUiListener.REFRESH_STRUCTURE
262508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                            : OnRefreshUiListener.REFRESH_DATA;
263508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    break;
264508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                case MSG_UPDATE_TIME:
265508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    synchronized (mLock) {
266508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                        if (!mResumed) {
267508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                            return;
268508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                        }
269508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    }
270508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    removeMessages(MSG_UPDATE_TIME);
271508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    Message m = obtainMessage(MSG_UPDATE_TIME);
272508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    sendMessageDelayed(m, TIME_UPDATE_DELAY);
273508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
274508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    if (mRefreshUiListener != null) {
275508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                        //Log.i("foo", "Refresh UI: " + mNextUpdate
276508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                        //        + " @ " + SystemClock.uptimeMillis());
277508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                        mRefreshUiListener.onRefreshUi(mNextUpdate);
278508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                        mNextUpdate = OnRefreshUiListener.REFRESH_TIME;
279508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    }
280508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    break;
281508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            }
282508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        }
283508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    };
284508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
285508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    // ----- DATA STRUCTURES -----
286508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
287508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    static interface OnRefreshUiListener {
288508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        public static final int REFRESH_TIME = 0;
289508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        public static final int REFRESH_DATA = 1;
290508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        public static final int REFRESH_STRUCTURE = 2;
291508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
292508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        public void onRefreshUi(int what);
293508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    }
294508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
295271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    static class UserState {
296271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        UserInfo mInfo;
297271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        String mLabel;
298271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        Drawable mIcon;
299271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    }
300271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
301728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    static class BaseItem {
302728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        final boolean mIsProcess;
303271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        final int mUserId;
304271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
305728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        PackageItemInfo mPackageInfo;
306728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        CharSequence mDisplayLabel;
307728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        String mLabel;
308728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        String mDescription;
309271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
310728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        int mCurSeq;
311271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
312728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        long mActiveSince;
313728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        long mSize;
314728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        String mSizeStr;
315728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        String mCurSizeStr;
316728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        boolean mNeedDivider;
3171337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        boolean mBackground;
318271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
319271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        public BaseItem(boolean isProcess, int userId) {
320728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            mIsProcess = isProcess;
321271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            mUserId = userId;
322271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        }
323271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
324271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        public Drawable loadIcon(Context context, RunningState state) {
325271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            if (mPackageInfo != null) {
326271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                return mPackageInfo.loadIcon(state.mPm);
327271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            }
328271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            return null;
329728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
330728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    }
331728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
332728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    static class ServiceItem extends BaseItem {
333728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        ActivityManager.RunningServiceInfo mRunningService;
334728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        ServiceInfo mServiceInfo;
335728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        boolean mShownAsStarted;
336728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
337728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        MergedItem mMergedItem;
338728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
339271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        public ServiceItem(int userId) {
340271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            super(false, userId);
341728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
342728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    }
343728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
344728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    static class ProcessItem extends BaseItem {
345728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        final HashMap<ComponentName, ServiceItem> mServices
346728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                = new HashMap<ComponentName, ServiceItem>();
347728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        final SparseArray<ProcessItem> mDependentProcesses
348728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                = new SparseArray<ProcessItem>();
349728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
350728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        final int mUid;
351728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        final String mProcessName;
352728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        int mPid;
353728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
354728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        ProcessItem mClient;
355728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        int mLastNumDependentProcesses;
356728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
357728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        int mRunningSeq;
358728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        ActivityManager.RunningAppProcessInfo mRunningProcessInfo;
359728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
360c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn        MergedItem mMergedItem;
361430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn
362430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn        boolean mInteresting;
363430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn
364728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        // Purely for sorting.
365728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        boolean mIsSystem;
366728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        boolean mIsStarted;
367728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        long mActiveSince;
368728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
369728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        public ProcessItem(Context context, int uid, String processName) {
370271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            super(true, UserHandle.getUserId(uid));
371728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            mDescription = context.getResources().getString(
372728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    R.string.service_process_name, processName);
373728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            mUid = uid;
374728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            mProcessName = processName;
375728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
376728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
377728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        void ensureLabel(PackageManager pm) {
378728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (mLabel != null) {
379728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                return;
380728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
381728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
382728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            try {
383c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn                ApplicationInfo ai = pm.getApplicationInfo(mProcessName,
384c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn                        PackageManager.GET_UNINSTALLED_PACKAGES);
385728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (ai.uid == mUid) {
386728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mDisplayLabel = ai.loadLabel(pm);
387728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mLabel = mDisplayLabel.toString();
388728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mPackageInfo = ai;
389728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    return;
390728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
391728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            } catch (PackageManager.NameNotFoundException e) {
392728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
393728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
394728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // If we couldn't get information about the overall
395728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // process, try to find something about the uid.
396728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            String[] pkgs = pm.getPackagesForUid(mUid);
397728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
398728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // If there is one package with this uid, that is what we want.
399728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (pkgs.length == 1) {
400728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                try {
401c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn                    ApplicationInfo ai = pm.getApplicationInfo(pkgs[0],
402c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn                            PackageManager.GET_UNINSTALLED_PACKAGES);
403728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mDisplayLabel = ai.loadLabel(pm);
404728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mLabel = mDisplayLabel.toString();
405728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mPackageInfo = ai;
406728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    return;
407728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                } catch (PackageManager.NameNotFoundException e) {
408728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
409728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
410728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
411728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // If there are multiple, see if one gives us the official name
412728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // for this uid.
413728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            for (String name : pkgs) {
414728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                try {
415728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    PackageInfo pi = pm.getPackageInfo(name, 0);
416728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    if (pi.sharedUserLabel != 0) {
417728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        CharSequence nm = pm.getText(name,
418728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                                pi.sharedUserLabel, pi.applicationInfo);
419728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        if (nm != null) {
420728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                            mDisplayLabel = nm;
421728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                            mLabel = nm.toString();
422728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                            mPackageInfo = pi.applicationInfo;
423728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                            return;
424728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        }
425728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    }
426728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                } catch (PackageManager.NameNotFoundException e) {
427728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
428728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
429728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
430728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // If still don't have anything to display, just use the
431728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // service info.
432728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (mServices.size() > 0) {
433271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                ApplicationInfo ai = mServices.values().iterator().next()
434728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        .mServiceInfo.applicationInfo;
435271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mPackageInfo = ai;
436728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                mDisplayLabel = mPackageInfo.loadLabel(pm);
437728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                mLabel = mDisplayLabel.toString();
438728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                return;
439728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
440728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
441728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // Finally... whatever, just pick the first package's name.
442728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            try {
443c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn                ApplicationInfo ai = pm.getApplicationInfo(pkgs[0],
444c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn                        PackageManager.GET_UNINSTALLED_PACKAGES);
445728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                mDisplayLabel = ai.loadLabel(pm);
446728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                mLabel = mDisplayLabel.toString();
447728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                mPackageInfo = ai;
448728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                return;
449728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            } catch (PackageManager.NameNotFoundException e) {
450728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
451728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
4527cb4780870fe72882c9b37e91d1b812f16998b3dJeff Sharkey
4530e092f4eb010976349e3fd1e49e41e14b1a33aaaJeff Sharkey        boolean updateService(Context context, ActivityManager.RunningServiceInfo service) {
4540e092f4eb010976349e3fd1e49e41e14b1a33aaaJeff Sharkey            final PackageManager pm = context.getPackageManager();
4557cb4780870fe72882c9b37e91d1b812f16998b3dJeff Sharkey
456728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            boolean changed = false;
457728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            ServiceItem si = mServices.get(service.service);
458728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (si == null) {
459728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                changed = true;
460271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                si = new ServiceItem(mUserId);
461728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                si.mRunningService = service;
462728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                try {
4630e092f4eb010976349e3fd1e49e41e14b1a33aaaJeff Sharkey                    si.mServiceInfo = ActivityThread.getPackageManager().getServiceInfo(
4640e092f4eb010976349e3fd1e49e41e14b1a33aaaJeff Sharkey                            service.service, PackageManager.GET_UNINSTALLED_PACKAGES,
4650e092f4eb010976349e3fd1e49e41e14b1a33aaaJeff Sharkey                            UserHandle.getUserId(service.uid));
466910b2116b0f1d3efdb95d663003a2181bf9faf33Johan Redestig
467910b2116b0f1d3efdb95d663003a2181bf9faf33Johan Redestig                    if (si.mServiceInfo == null) {
468910b2116b0f1d3efdb95d663003a2181bf9faf33Johan Redestig                        Log.d("RunningService", "getServiceInfo returned null for: "
469910b2116b0f1d3efdb95d663003a2181bf9faf33Johan Redestig                                + service.service);
470910b2116b0f1d3efdb95d663003a2181bf9faf33Johan Redestig                        return false;
471910b2116b0f1d3efdb95d663003a2181bf9faf33Johan Redestig                    }
4720e092f4eb010976349e3fd1e49e41e14b1a33aaaJeff Sharkey                } catch (RemoteException e) {
473728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
474728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                si.mDisplayLabel = makeLabel(pm,
475728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        si.mRunningService.service.getClassName(), si.mServiceInfo);
476728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                mLabel = mDisplayLabel != null ? mDisplayLabel.toString() : null;
477728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                si.mPackageInfo = si.mServiceInfo.applicationInfo;
478728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                mServices.put(service.service, si);
479728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
480728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            si.mCurSeq = mCurSeq;
481728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            si.mRunningService = service;
482728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            long activeSince = service.restarting == 0 ? service.activeSince : -1;
483728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (si.mActiveSince != activeSince) {
484728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                si.mActiveSince = activeSince;
485728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                changed = true;
486728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
487728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (service.clientPackage != null && service.clientLabel != 0) {
488728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (si.mShownAsStarted) {
489728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    si.mShownAsStarted = false;
490728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    changed = true;
491728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
492728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                try {
493728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    Resources clientr = pm.getResourcesForApplication(service.clientPackage);
494728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    String label = clientr.getString(service.clientLabel);
4950e092f4eb010976349e3fd1e49e41e14b1a33aaaJeff Sharkey                    si.mDescription = context.getResources().getString(
496728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                            R.string.service_client_name, label);
497728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                } catch (PackageManager.NameNotFoundException e) {
498728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    si.mDescription = null;
499728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
500728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            } else {
501728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (!si.mShownAsStarted) {
502728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    si.mShownAsStarted = true;
503728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    changed = true;
504728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
5050e092f4eb010976349e3fd1e49e41e14b1a33aaaJeff Sharkey                si.mDescription = context.getResources().getString(
506728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        R.string.service_started_by_app);
507728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
508728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
509728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            return changed;
510728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
511728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
5122826bc4ca52686f6863409e36eaea1a7f45de3ebDianne Hackborn        boolean updateSize(Context context, long pss, int curSeq) {
5132826bc4ca52686f6863409e36eaea1a7f45de3ebDianne Hackborn            mSize = pss * 1024;
514728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (mCurSeq == curSeq) {
515728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                String sizeStr = Formatter.formatShortFileSize(
516728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        context, mSize);
517728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (!sizeStr.equals(mSizeStr)){
518728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mSizeStr = sizeStr;
519728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    // We update this on the second tick where we update just
520728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    // the text in the current items, so no need to say we
521728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    // changed here.
522728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    return false;
523728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
524728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
525728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            return false;
526728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
527728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
528728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        boolean buildDependencyChain(Context context, PackageManager pm, int curSeq) {
529728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            final int NP = mDependentProcesses.size();
530728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            boolean changed = false;
531728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            for (int i=0; i<NP; i++) {
532728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                ProcessItem proc = mDependentProcesses.valueAt(i);
533728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (proc.mClient != this) {
534728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    changed = true;
535728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    proc.mClient = this;
536728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
537728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                proc.mCurSeq = curSeq;
538728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                proc.ensureLabel(pm);
539728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                changed |= proc.buildDependencyChain(context, pm, curSeq);
540728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
541728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
542728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (mLastNumDependentProcesses != mDependentProcesses.size()) {
543728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                changed = true;
544728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                mLastNumDependentProcesses = mDependentProcesses.size();
545728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
546728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
547728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            return changed;
548728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
549728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
550728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        void addDependentProcesses(ArrayList<BaseItem> dest,
551728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                ArrayList<ProcessItem> destProc) {
552728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            final int NP = mDependentProcesses.size();
553728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            for (int i=0; i<NP; i++) {
554728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                ProcessItem proc = mDependentProcesses.valueAt(i);
555728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                proc.addDependentProcesses(dest, destProc);
556728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                dest.add(proc);
557728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (proc.mPid > 0) {
558728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    destProc.add(proc);
559728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
560728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
561728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
562728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    }
563728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
564728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    static class MergedItem extends BaseItem {
565728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        ProcessItem mProcess;
566271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        UserState mUser;
567728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        final ArrayList<ProcessItem> mOtherProcesses = new ArrayList<ProcessItem>();
568728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        final ArrayList<ServiceItem> mServices = new ArrayList<ServiceItem>();
569271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        final ArrayList<MergedItem> mChildren = new ArrayList<MergedItem>();
570728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
5711337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        private int mLastNumProcesses = -1, mLastNumServices = -1;
5721337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn
573271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        MergedItem(int userId) {
574271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            super(false, userId);
575728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
576271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
577271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        private void setDescription(Context context, int numProcesses, int numServices) {
578271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            if (mLastNumProcesses != numProcesses || mLastNumServices != numServices) {
579271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mLastNumProcesses = numProcesses;
580271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mLastNumServices = numServices;
581271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                int resid = R.string.running_processes_item_description_s_s;
582271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (numProcesses != 1) {
583271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    resid = numServices != 1
584271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                            ? R.string.running_processes_item_description_p_p
585271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                            : R.string.running_processes_item_description_p_s;
586271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                } else if (numServices != 1) {
587271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    resid = R.string.running_processes_item_description_s_p;
588271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
589271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mDescription = context.getResources().getString(resid, numProcesses,
590271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        numServices);
591271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            }
592271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        }
593271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
5941337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        boolean update(Context context, boolean background) {
5951337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            mBackground = background;
596271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
597271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            if (mUser != null) {
598271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                // This is a merged item that contains a child collection
599271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                // of items...  that is, it is an entire user, containing
600271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                // everything associated with that user.  So set it up as such.
601271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                // For concrete stuff we need about the process of this item,
602271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                // we will just use the info from the first child.
603271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                MergedItem child0 = mChildren.get(0);
604271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mPackageInfo = child0.mProcess.mPackageInfo;
605271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mLabel = mUser != null ? mUser.mLabel : null;
606271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mDisplayLabel = mLabel;
607271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                int numProcesses = 0;
608271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                int numServices = 0;
609271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mActiveSince = -1;
610271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                for (int i=0; i<mChildren.size(); i++) {
611271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    MergedItem child = mChildren.get(i);
612271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    numProcesses += child.mLastNumProcesses;
613271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    numServices += child.mLastNumServices;
614271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    if (child.mActiveSince >= 0 && mActiveSince < child.mActiveSince) {
615271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        mActiveSince = child.mActiveSince;
6161337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                    }
6171337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                }
618271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (!mBackground) {
619271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    setDescription(context, numProcesses, numServices);
620271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
621271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            } else {
622271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mPackageInfo = mProcess.mPackageInfo;
623271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mDisplayLabel = mProcess.mDisplayLabel;
624271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mLabel = mProcess.mLabel;
625271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
626271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (!mBackground) {
627271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    setDescription(context, (mProcess.mPid > 0 ? 1 : 0) + mOtherProcesses.size(),
628271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                            mServices.size());
629271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
630271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
631271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mActiveSince = -1;
632271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                for (int i=0; i<mServices.size(); i++) {
633271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    ServiceItem si = mServices.get(i);
634271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    if (si.mActiveSince >= 0 && mActiveSince < si.mActiveSince) {
635271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        mActiveSince = si.mActiveSince;
636271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    }
637728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
638728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
639271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
640728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            return false;
641728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
642728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
643728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        boolean updateSize(Context context) {
644271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            if (mUser != null) {
645271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mSize = 0;
646271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                for (int i=0; i<mChildren.size(); i++) {
647271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    MergedItem child = mChildren.get(i);
648271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    child.updateSize(context);
649271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    mSize += child.mSize;
650271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
651271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            } else {
652271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mSize = mProcess.mSize;
653271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                for (int i=0; i<mOtherProcesses.size(); i++) {
654271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    mSize += mOtherProcesses.get(i).mSize;
655271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
656728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
657728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
658728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            String sizeStr = Formatter.formatShortFileSize(
659728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    context, mSize);
660728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (!sizeStr.equals(mSizeStr)){
661728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                mSizeStr = sizeStr;
662728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // We update this on the second tick where we update just
663728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // the text in the current items, so no need to say we
664728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // changed here.
665728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                return false;
666728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
667728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            return false;
668728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
669271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
670271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        public Drawable loadIcon(Context context, RunningState state) {
671271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            if (mUser == null) {
672271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                return super.loadIcon(context, state);
673271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            }
674271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            if (mUser.mIcon != null) {
675b0b0b110c04ddbbe5e2651dcb1a6f13551c61fb8Amith Yamasani                ConstantState constState = mUser.mIcon.getConstantState();
676b0b0b110c04ddbbe5e2651dcb1a6f13551c61fb8Amith Yamasani                if (constState == null) {
677b0b0b110c04ddbbe5e2651dcb1a6f13551c61fb8Amith Yamasani                    return mUser.mIcon;
678b0b0b110c04ddbbe5e2651dcb1a6f13551c61fb8Amith Yamasani                } else {
679b0b0b110c04ddbbe5e2651dcb1a6f13551c61fb8Amith Yamasani                    return constState.newDrawable();
680b0b0b110c04ddbbe5e2651dcb1a6f13551c61fb8Amith Yamasani                }
681271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            }
682271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            return context.getResources().getDrawable(
683271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    com.android.internal.R.drawable.ic_menu_cc);
684271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        }
685728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    }
686271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
687271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    class ServiceProcessComparator implements Comparator<ProcessItem> {
688728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        public int compare(ProcessItem object1, ProcessItem object2) {
689271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            if (object1.mUserId != object2.mUserId) {
690271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (object1.mUserId == mMyUserId) return -1;
691271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (object2.mUserId == mMyUserId) return 1;
692271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                return object1.mUserId < object2.mUserId ? -1 : 1;
693271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            }
694728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (object1.mIsStarted != object2.mIsStarted) {
695728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // Non-started processes go last.
696728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                return object1.mIsStarted ? -1 : 1;
697728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
698728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (object1.mIsSystem != object2.mIsSystem) {
699728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // System processes go below non-system.
700728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                return object1.mIsSystem ? 1 : -1;
701728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
702728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (object1.mActiveSince != object2.mActiveSince) {
703728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // Remaining ones are sorted with the longest running
704728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // services last.
705728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                return (object1.mActiveSince > object2.mActiveSince) ? -1 : 1;
706728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
707728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            return 0;
708728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
709728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    }
710728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
711728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    static CharSequence makeLabel(PackageManager pm,
712728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            String className, PackageItemInfo item) {
713728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        if (item != null && (item.labelRes != 0
714728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                || item.nonLocalizedLabel != null)) {
715728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            CharSequence label = item.loadLabel(pm);
716728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (label != null) {
717728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                return label;
718728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
719728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
720728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
721728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        String label = className;
722728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        int tail = label.lastIndexOf('.');
723728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        if (tail >= 0) {
724728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            label = label.substring(tail+1, label.length());
725728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
726728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        return label;
727728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    }
728728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
729508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    static RunningState getInstance(Context context) {
730508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        synchronized (sGlobalLock) {
731508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            if (sInstance == null) {
732508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                sInstance = new RunningState(context);
733508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            }
734508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            return sInstance;
735508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        }
736508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    }
737508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
738508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    private RunningState(Context context) {
739508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        mApplicationContext = context.getApplicationContext();
740508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        mAm = (ActivityManager)mApplicationContext.getSystemService(Context.ACTIVITY_SERVICE);
741508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        mPm = mApplicationContext.getPackageManager();
742271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        mUm = (UserManager)mApplicationContext.getSystemService(Context.USER_SERVICE);
743271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        mMyUserId = UserHandle.myUserId();
744508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        mResumed = false;
745508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        mBackgroundThread = new HandlerThread("RunningState:Background");
746508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        mBackgroundThread.start();
747508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        mBackgroundHandler = new BackgroundHandler(mBackgroundThread.getLooper());
748508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    }
749508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
750508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    void resume(OnRefreshUiListener listener) {
751508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        synchronized (mLock) {
752508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            mResumed = true;
753508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            mRefreshUiListener = listener;
7542372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn            if (mInterestingConfigChanges.applyNewConfig(mApplicationContext.getResources())) {
7552372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn                mHaveData = false;
7562372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn                mBackgroundHandler.removeMessages(MSG_RESET_CONTENTS);
7572372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn                mBackgroundHandler.removeMessages(MSG_UPDATE_CONTENTS);
7582372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn                mBackgroundHandler.sendEmptyMessage(MSG_RESET_CONTENTS);
7592372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn            }
760508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            if (!mBackgroundHandler.hasMessages(MSG_UPDATE_CONTENTS)) {
761508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                mBackgroundHandler.sendEmptyMessage(MSG_UPDATE_CONTENTS);
762508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            }
763508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            mHandler.sendEmptyMessage(MSG_UPDATE_TIME);
764508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        }
765508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    }
766508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
767508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    void updateNow() {
768508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        synchronized (mLock) {
769508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            mBackgroundHandler.removeMessages(MSG_UPDATE_CONTENTS);
770508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            mBackgroundHandler.sendEmptyMessage(MSG_UPDATE_CONTENTS);
771508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        }
772508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    }
773508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
774508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    boolean hasData() {
775508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        synchronized (mLock) {
776508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            return mHaveData;
777508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        }
778508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    }
779508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
780508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    void waitForData() {
781508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        synchronized (mLock) {
782508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            while (!mHaveData) {
783508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                try {
784508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                    mLock.wait(0);
785508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                } catch (InterruptedException e) {
786508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                }
787508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            }
788508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        }
789508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    }
790508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
791508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    void pause() {
792508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        synchronized (mLock) {
793508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            mResumed = false;
794508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            mRefreshUiListener = null;
795508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            mHandler.removeMessages(MSG_UPDATE_TIME);
796508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn        }
797508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    }
798508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn
7991337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn    private boolean isInterestingProcess(ActivityManager.RunningAppProcessInfo pi) {
8001337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        if ((pi.flags&ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE) != 0) {
8011337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            return true;
8021337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        }
8031337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        if ((pi.flags&ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT) == 0
804430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn                && pi.importance >= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
805430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn                && pi.importance < ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE
8061337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                && pi.importanceReasonCode
8071337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                        == ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN) {
8081337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            return true;
8091337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        }
8101337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        return false;
8111337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn    }
8121337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn
8132372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn    private void reset() {
8142372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn        mServiceProcessesByName.clear();
8152372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn        mServiceProcessesByPid.clear();
8162372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn        mInterestingProcesses.clear();
8172372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn        mRunningProcesses.clear();
8182372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn        mProcessItems.clear();
8192372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn        mAllProcessItems.clear();
820271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        mUsers.clear();
821271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    }
822271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
823271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn    private void addOtherUserItem(Context context, ArrayList<MergedItem> newMergedItems,
824271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            SparseArray<MergedItem> userItems, MergedItem newItem) {
825271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        MergedItem userItem = userItems.get(newItem.mUserId);
826271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        boolean first = userItem == null || userItem.mCurSeq != mSequence;
827271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        if (first) {
828271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            if (userItem == null) {
829271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                userItem = new MergedItem(newItem.mUserId);
830271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                userItems.put(newItem.mUserId, userItem);
831271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            } else {
832271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                userItem.mChildren.clear();
833271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            }
834271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            userItem.mCurSeq = mSequence;
835271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            if ((userItem.mUser=mUsers.get(newItem.mUserId)) == null) {
836271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                userItem.mUser = new UserState();
837271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                UserInfo info = mUm.getUserInfo(newItem.mUserId);
838271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                userItem.mUser.mInfo = info;
839c715fb1207361bb2a793752eefb02f1956075739Dianne Hackborn                if (info != null) {
84095b86a5488a27d95bda8b6db1f608d6ce55dae8aAlexandra Gherghina                    userItem.mUser.mIcon = Utils.getUserIcon(context, mUm, info);
841271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
842271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                String name = info != null ? info.name : null;
843bf427a2064e76cabc5e50573bcfcc0c954dd0720Jun Su                if (name == null && info != null) {
844271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    name = Integer.toString(info.id);
845bf427a2064e76cabc5e50573bcfcc0c954dd0720Jun Su                } else if (info == null) {
846bf427a2064e76cabc5e50573bcfcc0c954dd0720Jun Su                    name = context.getString(R.string.unknown);
847271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
848271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                userItem.mUser.mLabel = context.getResources().getString(
849271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        R.string.running_process_item_user_label, name);
850271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            }
851271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            newMergedItems.add(userItem);
852271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        }
853271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        userItem.mChildren.add(newItem);
8542372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn    }
8552372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn
856508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn    private boolean update(Context context, ActivityManager am) {
857728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        final PackageManager pm = context.getPackageManager();
858728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
859728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        mSequence++;
860728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
861728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        boolean changed = false;
8624bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn
8634bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        // Retrieve list of services, filtering out anything that definitely
8644bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        // won't be shown in the UI.
865728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        List<ActivityManager.RunningServiceInfo> services
866508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                = am.getRunningServices(MAX_SERVICES);
8674bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        int NS = services != null ? services.size() : 0;
868728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        for (int i=0; i<NS; i++) {
869728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            ActivityManager.RunningServiceInfo si = services.get(i);
870728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // We are not interested in services that have not been started
871728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // and don't have a known client, because
872728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // there is nothing the user can do about them.
873728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (!si.started && si.clientLabel == 0) {
8744bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                services.remove(i);
8754bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                i--;
8764bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                NS--;
877728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                continue;
878728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
879728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // We likewise don't care about services running in a
880728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // persistent process like the system or phone.
881728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if ((si.flags&ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS)
882728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    != 0) {
8834bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                services.remove(i);
8844bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                i--;
8854bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                NS--;
886728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                continue;
887728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
8884bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        }
8894bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn
8904bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        // Retrieve list of running processes, organizing them into a sparse
8914bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        // array for easy retrieval.
8924bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        List<ActivityManager.RunningAppProcessInfo> processes
8934bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                = am.getRunningAppProcesses();
8944bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        final int NP = processes != null ? processes.size() : 0;
8954bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        mTmpAppProcesses.clear();
8964bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        for (int i=0; i<NP; i++) {
8974bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            ActivityManager.RunningAppProcessInfo pi = processes.get(i);
8984bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            mTmpAppProcesses.put(pi.pid, new AppProcessInfo(pi));
8994bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        }
9004bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn
9014bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        // Initial iteration through running services to collect per-process
9024bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        // info about them.
9034bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        for (int i=0; i<NS; i++) {
9044bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            ActivityManager.RunningServiceInfo si = services.get(i);
9054bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            if (si.restarting == 0 && si.pid > 0) {
9064bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                AppProcessInfo ainfo = mTmpAppProcesses.get(si.pid);
9074bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                if (ainfo != null) {
9084bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                    ainfo.hasServices = true;
9094bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                    if (si.foreground) {
9104bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                        ainfo.hasForegroundServices = true;
9114bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                    }
9124bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                }
9134bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            }
9144bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        }
9154bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn
9164bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        // Update state we are maintaining about process that are running services.
9174bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn        for (int i=0; i<NS; i++) {
9184bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            ActivityManager.RunningServiceInfo si = services.get(i);
9194bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn
9204bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            // If this service's process is in use at a higher importance
9214bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            // due to another process bound to one of its services, then we
9224bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            // won't put it in the top-level list of services.  Instead we
9234bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            // want it to be included in the set of processes that the other
9244bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            // process needs.
9254bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            if (si.restarting == 0 && si.pid > 0) {
9264bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                AppProcessInfo ainfo = mTmpAppProcesses.get(si.pid);
9274bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                if (ainfo != null && !ainfo.hasForegroundServices) {
9284bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                    // This process does not have any foreground services.
9294bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                    // If its importance is greater than the service importance
9304bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                    // then there is something else more significant that is
9314bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                    // keeping it around that it should possibly be included as
9324bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                    // a part of instead of being shown by itself.
9334bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                    if (ainfo.info.importance
9344bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                            < ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE) {
9354bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                        // Follow process chain to see if there is something
9364bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                        // else that could be shown
9374bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                        boolean skip = false;
9384bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                        ainfo = mTmpAppProcesses.get(ainfo.info.importanceReasonPid);
9394bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                        while (ainfo != null) {
9404bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                            if (ainfo.hasServices || isInterestingProcess(ainfo.info)) {
9414bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                                skip = true;
9424bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                                break;
9434bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                            }
9444bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                            ainfo = mTmpAppProcesses.get(ainfo.info.importanceReasonPid);
9454bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                        }
9464bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                        if (skip) {
9474bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                            continue;
9484bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                        }
9494bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                    }
9504bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn                }
9514bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn            }
9524bed01d8727b106a1a6bd09a1d82309e1b0df040Dianne Hackborn
953c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn            HashMap<String, ProcessItem> procs = mServiceProcessesByName.get(si.uid);
954728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (procs == null) {
955728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                procs = new HashMap<String, ProcessItem>();
956c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                mServiceProcessesByName.put(si.uid, procs);
957728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
958728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            ProcessItem proc = procs.get(si.process);
959728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (proc == null) {
960728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                changed = true;
9610e092f4eb010976349e3fd1e49e41e14b1a33aaaJeff Sharkey                proc = new ProcessItem(context, si.uid, si.process);
962728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                procs.put(si.process, proc);
963728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
964728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
965728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (proc.mCurSeq != mSequence) {
966728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                int pid = si.restarting == 0 ? si.pid : 0;
967728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (pid != proc.mPid) {
968728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    changed = true;
969728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    if (proc.mPid != pid) {
970728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        if (proc.mPid != 0) {
971c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                            mServiceProcessesByPid.remove(proc.mPid);
972728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        }
973728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        if (pid != 0) {
974c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                            mServiceProcessesByPid.put(pid, proc);
975728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        }
976728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        proc.mPid = pid;
977728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    }
978728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
979728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                proc.mDependentProcesses.clear();
980728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                proc.mCurSeq = mSequence;
981728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
9820e092f4eb010976349e3fd1e49e41e14b1a33aaaJeff Sharkey            changed |= proc.updateService(context, si);
983728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
984728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
985728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        // Now update the map of other processes that are running (but
986728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        // don't have services actively running inside them).
987728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        for (int i=0; i<NP; i++) {
988728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            ActivityManager.RunningAppProcessInfo pi = processes.get(i);
989c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn            ProcessItem proc = mServiceProcessesByPid.get(pi.pid);
990728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (proc == null) {
991728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // This process is not one that is a direct container
992728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // of a service, so look for it in the secondary
993728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // running list.
994728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                proc = mRunningProcesses.get(pi.pid);
995728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (proc == null) {
996c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                    changed = true;
997728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    proc = new ProcessItem(context, pi.uid, pi.processName);
998728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    proc.mPid = pi.pid;
999728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mRunningProcesses.put(pi.pid, proc);
1000728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
1001728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                proc.mDependentProcesses.clear();
1002728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
1003c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn
10041337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            if (isInterestingProcess(pi)) {
10051337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                if (!mInterestingProcesses.contains(proc)) {
1006c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                    changed = true;
10071337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                    mInterestingProcesses.add(proc);
1008c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                }
1009c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                proc.mCurSeq = mSequence;
1010430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn                proc.mInteresting = true;
1011c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                proc.ensureLabel(pm);
1012430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn            } else {
1013430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn                proc.mInteresting = false;
1014c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn            }
1015c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn
1016728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            proc.mRunningSeq = mSequence;
1017728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            proc.mRunningProcessInfo = pi;
1018728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
1019430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn
1020728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        // Build the chains from client processes to the process they are
1021728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        // dependent on; also remove any old running processes.
1022728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        int NRP = mRunningProcesses.size();
1023b71efad62e1dc63d4b928e06419637ef1c3011edAmith Yamasani        for (int i = 0; i < NRP;) {
1024728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            ProcessItem proc = mRunningProcesses.valueAt(i);
1025728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (proc.mRunningSeq == mSequence) {
1026728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                int clientPid = proc.mRunningProcessInfo.importanceReasonPid;
1027728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (clientPid != 0) {
1028c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                    ProcessItem client = mServiceProcessesByPid.get(clientPid);
1029728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    if (client == null) {
1030728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        client = mRunningProcesses.get(clientPid);
1031728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    }
1032728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    if (client != null) {
1033728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        client.mDependentProcesses.put(proc.mPid, proc);
1034728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    }
1035728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                } else {
1036728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    // In this pass the process doesn't have a client.
1037c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                    // Clear to make sure that, if it later gets the same one,
1038c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                    // we will detect the change.
1039728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    proc.mClient = null;
1040728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
1041b71efad62e1dc63d4b928e06419637ef1c3011edAmith Yamasani                i++;
1042728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            } else {
1043c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                changed = true;
1044728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                mRunningProcesses.remove(mRunningProcesses.keyAt(i));
1045b71efad62e1dc63d4b928e06419637ef1c3011edAmith Yamasani                NRP--;
1046728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
1047728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
1048728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
10491337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        // Remove any old interesting processes.
10501337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        int NHP = mInterestingProcesses.size();
1051c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn        for (int i=0; i<NHP; i++) {
10521337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            ProcessItem proc = mInterestingProcesses.get(i);
1053430a3d3376cfa2c2a03d6f18d28577c34750102cDianne Hackborn            if (!proc.mInteresting || mRunningProcesses.get(proc.mPid) == null) {
1054c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                changed = true;
10551337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                mInterestingProcesses.remove(i);
1056c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                i--;
1057c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                NHP--;
1058c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn            }
1059c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn        }
1060c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn
1061728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        // Follow the tree from all primary service processes to all
1062728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        // processes they are dependent on, marking these processes as
1063728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        // still being active and determining if anything has changed.
1064c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn        final int NAP = mServiceProcessesByPid.size();
1065728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        for (int i=0; i<NAP; i++) {
1066c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn            ProcessItem proc = mServiceProcessesByPid.valueAt(i);
1067728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (proc.mCurSeq == mSequence) {
1068728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                changed |= proc.buildDependencyChain(context, pm, mSequence);
1069728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
1070728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
1071728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
1072728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        // Look for services and their primary processes that no longer exist...
10738258dc23d3584d8ca2b0ddade6fb84adb86e4866Johannes Carlsson        ArrayList<Integer> uidToDelete = null;
1074c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn        for (int i=0; i<mServiceProcessesByName.size(); i++) {
1075c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn            HashMap<String, ProcessItem> procs = mServiceProcessesByName.valueAt(i);
1076728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            Iterator<ProcessItem> pit = procs.values().iterator();
1077728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            while (pit.hasNext()) {
1078728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                ProcessItem pi = pit.next();
1079728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (pi.mCurSeq == mSequence) {
1080728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    pi.ensureLabel(pm);
1081728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    if (pi.mPid == 0) {
1082728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        // Sanity: a non-process can't be dependent on
1083728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        // anything.
1084728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        pi.mDependentProcesses.clear();
1085728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    }
1086728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                } else {
1087728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    changed = true;
1088728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    pit.remove();
1089728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    if (procs.size() == 0) {
10908258dc23d3584d8ca2b0ddade6fb84adb86e4866Johannes Carlsson                        if (uidToDelete == null) {
10918258dc23d3584d8ca2b0ddade6fb84adb86e4866Johannes Carlsson                            uidToDelete = new ArrayList<Integer>();
10928258dc23d3584d8ca2b0ddade6fb84adb86e4866Johannes Carlsson                        }
10938258dc23d3584d8ca2b0ddade6fb84adb86e4866Johannes Carlsson                        uidToDelete.add(mServiceProcessesByName.keyAt(i));
1094728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    }
1095728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    if (pi.mPid != 0) {
1096c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                        mServiceProcessesByPid.remove(pi.mPid);
1097728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    }
1098728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    continue;
1099728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
1100728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                Iterator<ServiceItem> sit = pi.mServices.values().iterator();
1101728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                while (sit.hasNext()) {
1102728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    ServiceItem si = sit.next();
1103728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    if (si.mCurSeq != mSequence) {
1104728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        changed = true;
1105728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        sit.remove();
1106728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    }
1107728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
1108728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
1109728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
1110728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
11118258dc23d3584d8ca2b0ddade6fb84adb86e4866Johannes Carlsson        if (uidToDelete != null) {
11128258dc23d3584d8ca2b0ddade6fb84adb86e4866Johannes Carlsson            for (int i = 0; i < uidToDelete.size(); i++) {
11138258dc23d3584d8ca2b0ddade6fb84adb86e4866Johannes Carlsson                int uid = uidToDelete.get(i);
11148258dc23d3584d8ca2b0ddade6fb84adb86e4866Johannes Carlsson                mServiceProcessesByName.remove(uid);
11158258dc23d3584d8ca2b0ddade6fb84adb86e4866Johannes Carlsson            }
11168258dc23d3584d8ca2b0ddade6fb84adb86e4866Johannes Carlsson        }
11178258dc23d3584d8ca2b0ddade6fb84adb86e4866Johannes Carlsson
1118728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        if (changed) {
1119728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            // First determine an order for the services.
1120728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            ArrayList<ProcessItem> sortedProcesses = new ArrayList<ProcessItem>();
1121c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn            for (int i=0; i<mServiceProcessesByName.size(); i++) {
1122c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                for (ProcessItem pi : mServiceProcessesByName.valueAt(i).values()) {
1123728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    pi.mIsSystem = false;
1124728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    pi.mIsStarted = true;
1125728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    pi.mActiveSince = Long.MAX_VALUE;
1126728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    for (ServiceItem si : pi.mServices.values()) {
1127728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        if (si.mServiceInfo != null
1128728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                                && (si.mServiceInfo.applicationInfo.flags
1129728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
1130728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                            pi.mIsSystem = true;
1131728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        }
1132728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        if (si.mRunningService != null
1133728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                                && si.mRunningService.clientLabel != 0) {
1134728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                            pi.mIsStarted = false;
1135728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                            if (pi.mActiveSince > si.mRunningService.activeSince) {
1136728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                                pi.mActiveSince = si.mRunningService.activeSince;
1137728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                            }
1138728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        }
1139728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    }
1140728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    sortedProcesses.add(pi);
1141728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
1142728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
1143728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
1144728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            Collections.sort(sortedProcesses, mServiceProcessComparator);
1145728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
1146728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            ArrayList<BaseItem> newItems = new ArrayList<BaseItem>();
1147728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            ArrayList<MergedItem> newMergedItems = new ArrayList<MergedItem>();
1148271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            SparseArray<MergedItem> otherUsers = null;
1149728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            mProcessItems.clear();
1150728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            for (int i=0; i<sortedProcesses.size(); i++) {
1151728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                ProcessItem pi = sortedProcesses.get(i);
1152728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                pi.mNeedDivider = false;
1153728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
1154728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                int firstProc = mProcessItems.size();
1155728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // First add processes we are dependent on.
1156728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                pi.addDependentProcesses(newItems, mProcessItems);
1157728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // And add the process itself.
1158728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                newItems.add(pi);
1159728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (pi.mPid > 0) {
1160728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mProcessItems.add(pi);
1161728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
1162728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
1163728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // Now add the services running in it.
1164728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                MergedItem mergedItem = null;
1165728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                boolean haveAllMerged = false;
1166728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                boolean needDivider = false;
1167728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                for (ServiceItem si : pi.mServices.values()) {
1168728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    si.mNeedDivider = needDivider;
1169728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    needDivider = true;
1170728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    newItems.add(si);
1171728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    if (si.mMergedItem != null) {
1172728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        if (mergedItem != null && mergedItem != si.mMergedItem) {
1173728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                            haveAllMerged = false;
1174728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        }
1175728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        mergedItem = si.mMergedItem;
1176728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    } else {
1177728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        haveAllMerged = false;
1178728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    }
1179728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
1180728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
1181728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (!haveAllMerged || mergedItem == null
1182728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        || mergedItem.mServices.size() != pi.mServices.size()) {
1183728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    // Whoops, we need to build a new MergedItem!
1184271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    mergedItem = new MergedItem(pi.mUserId);
1185728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    for (ServiceItem si : pi.mServices.values()) {
1186728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        mergedItem.mServices.add(si);
1187728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        si.mMergedItem = mergedItem;
1188728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    }
1189728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mergedItem.mProcess = pi;
1190728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mergedItem.mOtherProcesses.clear();
1191728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    for (int mpi=firstProc; mpi<(mProcessItems.size()-1); mpi++) {
1192728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        mergedItem.mOtherProcesses.add(mProcessItems.get(mpi));
1193728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    }
1194728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
1195728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
11961337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                mergedItem.update(context, false);
1197271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (mergedItem.mUserId != mMyUserId) {
1198271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    addOtherUserItem(context, newMergedItems, mOtherUserMergedItems, mergedItem);
1199271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                } else {
1200271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    newMergedItems.add(mergedItem);
1201271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
1202728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
1203271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
12041337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            // Finally, interesting processes need to be shown and will
1205c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn            // go at the top.
12061337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            NHP = mInterestingProcesses.size();
1207c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn            for (int i=0; i<NHP; i++) {
12081337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                ProcessItem proc = mInterestingProcesses.get(i);
1209c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                if (proc.mClient == null && proc.mServices.size() <= 0) {
1210c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                    if (proc.mMergedItem == null) {
1211271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        proc.mMergedItem = new MergedItem(proc.mUserId);
1212c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                        proc.mMergedItem.mProcess = proc;
1213c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                    }
12141337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                    proc.mMergedItem.update(context, false);
1215271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    if (proc.mMergedItem.mUserId != mMyUserId) {
1216271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        addOtherUserItem(context, newMergedItems, mOtherUserMergedItems,
1217271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                                proc.mMergedItem);
1218271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    } else {
1219271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        newMergedItems.add(0, proc.mMergedItem);
1220271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    }
1221c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                    mProcessItems.add(proc);
1222c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn                }
1223c01b0c83fca571229621d16b757a46dc0fae7dfeDianne Hackborn            }
1224271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
1225271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            // Finally finally, user aggregated merged items need to be
1226271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            // updated now that they have all of their children.
1227271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            final int NU = mOtherUserMergedItems.size();
1228271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            for (int i=0; i<NU; i++) {
1229271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                MergedItem user = mOtherUserMergedItems.valueAt(i);
1230271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                if (user.mCurSeq == mSequence) {
1231271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    user.update(context, false);
1232271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
1233271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            }
1234271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
1235728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            synchronized (mLock) {
1236728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                mItems = newItems;
1237728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                mMergedItems = newMergedItems;
1238728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
1239728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
1240728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
1241728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        // Count number of interesting other (non-active) processes, and
1242728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        // build a list of all processes we will retrieve memory for.
1243728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        mAllProcessItems.clear();
1244728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        mAllProcessItems.addAll(mProcessItems);
1245728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        int numBackgroundProcesses = 0;
1246728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        int numForegroundProcesses = 0;
1247728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        int numServiceProcesses = 0;
1248728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        NRP = mRunningProcesses.size();
1249728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        for (int i=0; i<NRP; i++) {
1250728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            ProcessItem proc = mRunningProcesses.valueAt(i);
1251728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            if (proc.mCurSeq != mSequence) {
1252728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // We didn't hit this process as a dependency on one
1253728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                // of our active ones, so add it up if needed.
1254728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (proc.mRunningProcessInfo.importance >=
1255728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
1256728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    numBackgroundProcesses++;
1257728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mAllProcessItems.add(proc);
1258728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                } else if (proc.mRunningProcessInfo.importance <=
1259728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
1260728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    numForegroundProcesses++;
1261728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    mAllProcessItems.add(proc);
1262728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                } else {
1263ea38e678537cf740b5f30c1d69c7a332e98cdd2cDianne Hackborn                    Log.i("RunningState", "Unknown non-service process: "
1264728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                            + proc.mProcessName + " #" + proc.mPid);
1265728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
1266728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            } else {
1267728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                numServiceProcesses++;
1268728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
1269728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
1270728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
1271728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        long backgroundProcessMemory = 0;
1272728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        long foregroundProcessMemory = 0;
1273728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        long serviceProcessMemory = 0;
12741337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        ArrayList<MergedItem> newBackgroundItems = null;
1275271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        ArrayList<MergedItem> newUserBackgroundItems = null;
1276271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        boolean diffUsers = false;
1277728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        try {
1278728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            final int numProc = mAllProcessItems.size();
1279728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            int[] pids = new int[numProc];
1280728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            for (int i=0; i<numProc; i++) {
1281728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                pids[i] = mAllProcessItems.get(i).mPid;
1282728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
12832826bc4ca52686f6863409e36eaea1a7f45de3ebDianne Hackborn            long[] pss = ActivityManagerNative.getDefault()
12842826bc4ca52686f6863409e36eaea1a7f45de3ebDianne Hackborn                    .getProcessPss(pids);
12851337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            int bgIndex = 0;
12861337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            for (int i=0; i<pids.length; i++) {
1287728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                ProcessItem proc = mAllProcessItems.get(i);
12882826bc4ca52686f6863409e36eaea1a7f45de3ebDianne Hackborn                changed |= proc.updateSize(context, pss[i], mSequence);
1289728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                if (proc.mCurSeq == mSequence) {
1290728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    serviceProcessMemory += proc.mSize;
1291728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                } else if (proc.mRunningProcessInfo.importance >=
1292728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
1293728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    backgroundProcessMemory += proc.mSize;
12941337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                    MergedItem mergedItem;
12951337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                    if (newBackgroundItems != null) {
1296271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        mergedItem = proc.mMergedItem = new MergedItem(proc.mUserId);
12971337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                        proc.mMergedItem.mProcess = proc;
1298271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        diffUsers |= mergedItem.mUserId != mMyUserId;
12991337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                        newBackgroundItems.add(mergedItem);
13001337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                    } else {
13011337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                        if (bgIndex >= mBackgroundItems.size()
13021337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                                || mBackgroundItems.get(bgIndex).mProcess != proc) {
13031337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                            newBackgroundItems = new ArrayList<MergedItem>(numBackgroundProcesses);
13041337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                            for (int bgi=0; bgi<bgIndex; bgi++) {
1305271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                                mergedItem = mBackgroundItems.get(bgi);
1306271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                                diffUsers |= mergedItem.mUserId != mMyUserId;
1307271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                                newBackgroundItems.add(mergedItem);
13081337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                            }
1309271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                            mergedItem = proc.mMergedItem = new MergedItem(proc.mUserId);
13101337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                            proc.mMergedItem.mProcess = proc;
1311271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                            diffUsers |= mergedItem.mUserId != mMyUserId;
13121337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                            newBackgroundItems.add(mergedItem);
13131337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                        } else {
13141337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                            mergedItem = mBackgroundItems.get(bgIndex);
13151337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                        }
13161337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                    }
13171337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                    mergedItem.update(context, true);
13181337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                    mergedItem.updateSize(context);
13191337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                    bgIndex++;
1320728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                } else if (proc.mRunningProcessInfo.importance <=
1321728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                        ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
1322728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                    foregroundProcessMemory += proc.mSize;
1323728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn                }
1324728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            }
1325728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        } catch (RemoteException e) {
1326728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
1327728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
13281337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        if (newBackgroundItems == null) {
13292372ba5b54f018cbc2e01f66b661c2e322d174d7Dianne Hackborn            // One or more at the bottom may no longer exist.
13301337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            if (mBackgroundItems.size() > numBackgroundProcesses) {
13311337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                newBackgroundItems = new ArrayList<MergedItem>(numBackgroundProcesses);
13321337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                for (int bgi=0; bgi<numBackgroundProcesses; bgi++) {
1333271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    MergedItem mergedItem = mBackgroundItems.get(bgi);
1334271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    diffUsers |= mergedItem.mUserId != mMyUserId;
1335271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    newBackgroundItems.add(mergedItem);
1336271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
1337271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            }
1338271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        }
1339271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn
1340271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn        if (newBackgroundItems != null) {
1341271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            // The background items have changed; we need to re-build the
1342271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            // per-user items.
1343271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            if (!diffUsers) {
1344271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                // Easy: there are no other users, we can just use the same array.
1345271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                newUserBackgroundItems = newBackgroundItems;
1346271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            } else {
1347271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                // We now need to re-build the per-user list so that background
1348271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                // items for users are collapsed together.
1349271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                newUserBackgroundItems = new ArrayList<MergedItem>();
1350271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                final int NB = newBackgroundItems.size();
1351271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                for (int i=0; i<NB; i++) {
1352271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    MergedItem mergedItem = newBackgroundItems.get(i);
1353271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    if (mergedItem.mUserId != mMyUserId) {
1354271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        addOtherUserItem(context, newUserBackgroundItems,
1355271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                                mOtherUserBackgroundItems, mergedItem);
1356271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    } else {
1357271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        newUserBackgroundItems.add(mergedItem);
1358271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    }
1359271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                }
1360271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                // And user aggregated merged items need to be
1361271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                // updated now that they have all of their children.
1362271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                final int NU = mOtherUserBackgroundItems.size();
1363271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                for (int i=0; i<NU; i++) {
1364271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    MergedItem user = mOtherUserBackgroundItems.valueAt(i);
1365271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    if (user.mCurSeq == mSequence) {
1366271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        user.update(context, true);
1367271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                        user.updateSize(context);
1368271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                    }
13691337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                }
13701337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            }
13711337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        }
13721337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn
1373728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        for (int i=0; i<mMergedItems.size(); i++) {
1374728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            mMergedItems.get(i).updateSize(context);
1375728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
1376728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
1377728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        synchronized (mLock) {
1378728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            mNumBackgroundProcesses = numBackgroundProcesses;
1379728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            mNumForegroundProcesses = numForegroundProcesses;
1380728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            mNumServiceProcesses = numServiceProcesses;
1381728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            mBackgroundProcessMemory = backgroundProcessMemory;
1382728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            mForegroundProcessMemory = foregroundProcessMemory;
1383728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            mServiceProcessMemory = serviceProcessMemory;
13841337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            if (newBackgroundItems != null) {
13851337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                mBackgroundItems = newBackgroundItems;
1386271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn                mUserBackgroundItems = newUserBackgroundItems;
13871337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                if (mWatchingBackgroundItems) {
13881337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                    changed = true;
13891337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn                }
13901337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            }
1391508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            if (!mHaveData) {
1392508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                mHaveData = true;
1393508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn                mLock.notifyAll();
1394508fedc4102790dcd7004e4962e2b540967b714bDianne Hackborn            }
1395728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
1396728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
1397728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        return changed;
1398728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    }
1399728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
1400728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    ArrayList<BaseItem> getCurrentItems() {
1401728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        synchronized (mLock) {
1402728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            return mItems;
1403728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
1404728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    }
1405728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn
14061337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn    void setWatchingBackgroundItems(boolean watching) {
14071337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        synchronized (mLock) {
14081337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn            mWatchingBackgroundItems = watching;
14091337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        }
14101337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn    }
14111337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn
1412728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    ArrayList<MergedItem> getCurrentMergedItems() {
1413728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        synchronized (mLock) {
1414728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn            return mMergedItems;
1415728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn        }
1416728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn    }
14171337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn
14181337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn    ArrayList<MergedItem> getCurrentBackgroundItems() {
14191337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        synchronized (mLock) {
1420271c8b06c2b6f12cd7f51c2be2ca50167b96e742Dianne Hackborn            return mUserBackgroundItems;
14211337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn        }
14221337d0f70b18dd732c6a617be83e5be0bb8f2f87Dianne Hackborn    }
1423728ac35373028b79205a788c526ef4b495518ec1Dianne Hackborn}
1424