ProcessRecord.java revision fd12af4e768fec852c4c5dfee3b9bd7403b4b347
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.os.BatteryStatsImpl;
20import com.android.server.Watchdog;
21
22import android.app.ActivityManager;
23import android.app.Dialog;
24import android.app.IApplicationThread;
25import android.app.IInstrumentationWatcher;
26import android.content.ComponentName;
27import android.content.pm.ApplicationInfo;
28import android.os.Bundle;
29import android.os.IBinder;
30import android.os.RemoteException;
31import android.util.PrintWriterPrinter;
32
33import java.io.PrintWriter;
34import java.util.ArrayList;
35import java.util.HashMap;
36import java.util.HashSet;
37
38/**
39 * Full information about a particular process that
40 * is currently running.
41 */
42class ProcessRecord implements Watchdog.PssRequestor {
43    final BatteryStatsImpl.Uid.Proc batteryStats; // where to collect runtime statistics
44    final ApplicationInfo info; // all about the first app in the process
45    final String processName;   // name of the process
46    // List of packages running in the process
47    final HashSet<String> pkgList = new HashSet();
48    IApplicationThread thread;  // the actual proc...  may be null only if
49                                // 'persistent' is true (in which case we
50                                // are in the process of launching the app)
51    int pid;                    // The process of this application; 0 if none
52    boolean starting;           // True if the process is being started
53    int maxAdj;                 // Maximum OOM adjustment for this process
54    int hiddenAdj;              // If hidden, this is the adjustment to use
55    int curRawAdj;              // Current OOM unlimited adjustment for this process
56    int setRawAdj;              // Last set OOM unlimited adjustment for this process
57    int curAdj;                 // Current OOM adjustment for this process
58    int setAdj;                 // Last set OOM adjustment for this process
59    int curSchedGroup;          // Currently desired scheduling class
60    int setSchedGroup;          // Last set to background scheduling class
61    boolean setIsForeground;    // Running foreground UI when last set?
62    boolean foregroundServices; // Running any services that are foreground?
63    boolean bad;                // True if disabled in the bad process list
64    IBinder forcingToForeground;// Token that is forcing this process to be foreground
65    int adjSeq;                 // Sequence id for identifying repeated trav
66    ComponentName instrumentationClass;// class installed to instrument app
67    ApplicationInfo instrumentationInfo; // the application being instrumented
68    String instrumentationProfileFile; // where to save profiling
69    IInstrumentationWatcher instrumentationWatcher; // who is waiting
70    Bundle instrumentationArguments;// as given to us
71    ComponentName instrumentationResultClass;// copy of instrumentationClass
72    BroadcastRecord curReceiver;// receiver currently running in the app
73    long lastRequestedGc;       // When we last asked the app to do a gc
74    long lastLowMemory;         // When we last told the app that memory is low
75    boolean reportLowMemory;    // Set to true when waiting to report low mem
76    int lastPss;                // Last pss size reported by app.
77    String adjType;             // Debugging: primary thing impacting oom_adj.
78    Object adjSource;           // Debugging: option dependent object.
79    Object adjTarget;           // Debugging: target component impacting oom_adj.
80
81    // contains HistoryRecord objects
82    final ArrayList activities = new ArrayList();
83    // all ServiceRecord running in this process
84    final HashSet services = new HashSet();
85    // services that are currently executing code (need to remain foreground).
86    final HashSet<ServiceRecord> executingServices
87             = new HashSet<ServiceRecord>();
88    // All ConnectionRecord this process holds
89    final HashSet<ConnectionRecord> connections
90            = new HashSet<ConnectionRecord>();
91    // all IIntentReceivers that are registered from this process.
92    final HashSet<ReceiverList> receivers = new HashSet<ReceiverList>();
93    // class (String) -> ContentProviderRecord
94    final HashMap pubProviders = new HashMap();
95    // All ContentProviderRecord process is using
96    final HashSet conProviders = new HashSet();
97
98    boolean persistent;         // always keep this application running?
99    boolean crashing;           // are we in the process of crashing?
100    Dialog crashDialog;         // dialog being displayed due to crash.
101    boolean notResponding;      // does the app have a not responding dialog?
102    Dialog anrDialog;           // dialog being displayed due to app not resp.
103    boolean removed;            // has app package been removed from device?
104    boolean debugging;          // was app launched for debugging?
105    int persistentActivities;   // number of activities that are persistent
106    boolean waitedForDebugger;  // has process show wait for debugger dialog?
107    Dialog waitDialog;          // current wait for debugger dialog
108
109    String stringName;          // caching of toString() result.
110
111    // These reports are generated & stored when an app gets into an error condition.
112    // They will be "null" when all is OK.
113    ActivityManager.ProcessErrorStateInfo crashingReport;
114    ActivityManager.ProcessErrorStateInfo notRespondingReport;
115
116    // Who will be notified of the error. This is usually an activity in the
117    // app that installed the package.
118    ComponentName errorReportReceiver;
119
120    void dump(PrintWriter pw, String prefix) {
121        if (info.className != null) {
122            pw.print(prefix); pw.print("class="); pw.println(info.className);
123        }
124        if (info.manageSpaceActivityName != null) {
125            pw.print(prefix); pw.print("manageSpaceActivityName=");
126            pw.println(info.manageSpaceActivityName);
127        }
128        pw.print(prefix); pw.print("dir="); pw.print(info.sourceDir);
129                pw.print(" publicDir="); pw.print(info.publicSourceDir);
130                pw.print(" data="); pw.println(info.dataDir);
131        pw.print(prefix); pw.print("packageList="); pw.println(pkgList);
132        if (instrumentationClass != null || instrumentationProfileFile != null
133                || instrumentationArguments != null) {
134            pw.print(prefix); pw.print("instrumentationClass=");
135                    pw.print(instrumentationClass);
136                    pw.print(" instrumentationProfileFile=");
137                    pw.println(instrumentationProfileFile);
138            pw.print(prefix); pw.print("instrumentationArguments=");
139                    pw.println(instrumentationArguments);
140            pw.print(prefix); pw.print("instrumentationInfo=");
141                    pw.println(instrumentationInfo);
142            if (instrumentationInfo != null) {
143                instrumentationInfo.dump(new PrintWriterPrinter(pw), prefix + "  ");
144            }
145        }
146        pw.print(prefix); pw.print("thread="); pw.print(thread);
147                pw.print(" curReceiver="); pw.println(curReceiver);
148        pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
149                pw.print(starting); pw.print(" lastPss="); pw.println(lastPss);
150        pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
151                pw.print(" hidden="); pw.print(hiddenAdj);
152                pw.print(" curRaw="); pw.print(curRawAdj);
153                pw.print(" setRaw="); pw.print(setRawAdj);
154                pw.print(" cur="); pw.print(curAdj);
155                pw.print(" set="); pw.println(setAdj);
156        pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup);
157                pw.print(" setSchedGroup="); pw.println(setSchedGroup);
158        pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
159                pw.print(" foregroundServices="); pw.print(foregroundServices);
160                pw.print(" forcingToForeground="); pw.println(forcingToForeground);
161        pw.print(prefix); pw.print("persistent="); pw.print(persistent);
162                pw.print(" removed="); pw.print(removed);
163                pw.print(" persistentActivities="); pw.println(persistentActivities);
164        if (debugging || crashing || crashDialog != null || notResponding
165                || anrDialog != null || bad) {
166            pw.print(prefix); pw.print("debugging="); pw.print(debugging);
167                    pw.print(" crashing="); pw.print(crashing);
168                    pw.print(" "); pw.print(crashDialog);
169                    pw.print(" notResponding="); pw.print(notResponding);
170                    pw.print(" " ); pw.print(anrDialog);
171                    pw.print(" bad="); pw.print(bad);
172
173                    // crashing or notResponding is always set before errorReportReceiver
174                    if (errorReportReceiver != null) {
175                        pw.print(" errorReportReceiver=");
176                        pw.print(errorReportReceiver.flattenToShortString());
177                    }
178                    pw.println();
179        }
180        if (activities.size() > 0) {
181            pw.print(prefix); pw.print("activities="); pw.println(activities);
182        }
183        if (services.size() > 0) {
184            pw.print(prefix); pw.print("services="); pw.println(services);
185        }
186        if (executingServices.size() > 0) {
187            pw.print(prefix); pw.print("executingServices="); pw.println(executingServices);
188        }
189        if (connections.size() > 0) {
190            pw.print(prefix); pw.print("connections="); pw.println(connections);
191        }
192        if (pubProviders.size() > 0) {
193            pw.print(prefix); pw.print("pubProviders="); pw.println(pubProviders);
194        }
195        if (conProviders.size() > 0) {
196            pw.print(prefix); pw.print("conProviders="); pw.println(conProviders);
197        }
198        if (receivers.size() > 0) {
199            pw.print(prefix); pw.print("receivers="); pw.println(receivers);
200        }
201    }
202
203    ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread,
204            ApplicationInfo _info, String _processName) {
205        batteryStats = _batteryStats;
206        info = _info;
207        processName = _processName;
208        pkgList.add(_info.packageName);
209        thread = _thread;
210        maxAdj = ActivityManagerService.EMPTY_APP_ADJ;
211        hiddenAdj = ActivityManagerService.HIDDEN_APP_MIN_ADJ;
212        curRawAdj = setRawAdj = -100;
213        curAdj = setAdj = -100;
214        persistent = false;
215        removed = false;
216        persistentActivities = 0;
217    }
218
219    public void setPid(int _pid) {
220        pid = _pid;
221        stringName = null;
222    }
223
224    /**
225     * This method returns true if any of the activities within the process record are interesting
226     * to the user. See HistoryRecord.isInterestingToUserLocked()
227     */
228    public boolean isInterestingToUserLocked() {
229        final int size = activities.size();
230        for (int i = 0 ; i < size ; i++) {
231            HistoryRecord r = (HistoryRecord) activities.get(i);
232            if (r.isInterestingToUserLocked()) {
233                return true;
234            }
235        }
236        return false;
237    }
238
239    public void stopFreezingAllLocked() {
240        int i = activities.size();
241        while (i > 0) {
242            i--;
243            ((HistoryRecord)activities.get(i)).stopFreezingScreenLocked(true);
244        }
245    }
246
247    public void requestPss() {
248        IApplicationThread localThread = thread;
249        if (localThread != null) {
250            try {
251                localThread.requestPss();
252            } catch (RemoteException e) {
253            }
254        }
255    }
256
257    public String toString() {
258        if (stringName != null) {
259            return stringName;
260        }
261        StringBuilder sb = new StringBuilder(128);
262        sb.append("ProcessRecord{");
263        sb.append(Integer.toHexString(System.identityHashCode(this)));
264        sb.append(' ');
265        sb.append(pid);
266        sb.append(':');
267        sb.append(processName);
268        sb.append('/');
269        sb.append(info.uid);
270        sb.append('}');
271        return stringName = sb.toString();
272    }
273
274    /*
275     *  Return true if package has been added false if not
276     */
277    public boolean addPackage(String pkg) {
278        if (!pkgList.contains(pkg)) {
279            pkgList.add(pkg);
280            return true;
281        }
282        return false;
283    }
284
285    /*
286     *  Delete all packages from list except the package indicated in info
287     */
288    public void resetPackageList() {
289        pkgList.clear();
290        pkgList.add(info.packageName);
291    }
292
293    public String[] getPackageList() {
294        int size = pkgList.size();
295        if (size == 0) {
296            return null;
297        }
298        String list[] = new String[size];
299        pkgList.toArray(list);
300        return list;
301    }
302}
303