ProcessRecord.java revision f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8
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;
20
21import android.app.ActivityManager;
22import android.app.Dialog;
23import android.app.IApplicationThread;
24import android.app.IInstrumentationWatcher;
25import android.content.ComponentName;
26import android.content.Context;
27import android.content.pm.ApplicationInfo;
28import android.content.res.CompatibilityInfo;
29import android.os.Bundle;
30import android.os.IBinder;
31import android.os.Process;
32import android.os.SystemClock;
33import android.os.UserHandle;
34import android.util.PrintWriterPrinter;
35import android.util.TimeUtils;
36
37import java.io.PrintWriter;
38import java.util.ArrayList;
39import java.util.HashMap;
40import java.util.HashSet;
41
42/**
43 * Full information about a particular process that
44 * is currently running.
45 */
46class ProcessRecord {
47    final BatteryStatsImpl.Uid.Proc batteryStats; // where to collect runtime statistics
48    final ApplicationInfo info; // all about the first app in the process
49    final boolean isolated;     // true if this is a special isolated process
50    final int uid;              // uid of process; may be different from 'info' if isolated
51    final int userId;           // user of process.
52    final String processName;   // name of the process
53    // List of packages running in the process
54    final HashSet<String> pkgList = new HashSet<String>();
55    IApplicationThread thread;  // the actual proc...  may be null only if
56                                // 'persistent' is true (in which case we
57                                // are in the process of launching the app)
58    int pid;                    // The process of this application; 0 if none
59    boolean starting;           // True if the process is being started
60    long lastActivityTime;      // For managing the LRU list
61    long lruWeight;             // Weight for ordering in LRU list
62    int maxAdj;                 // Maximum OOM adjustment for this process
63    int hiddenAdj;              // If hidden, this is the adjustment to use
64    int emptyAdj;               // If empty, this is the adjustment to use
65    int curRawAdj;              // Current OOM unlimited adjustment for this process
66    int setRawAdj;              // Last set OOM unlimited adjustment for this process
67    int nonStoppingAdj;         // Adjustment not counting any stopping activities
68    int curAdj;                 // Current OOM adjustment for this process
69    int setAdj;                 // Last set OOM adjustment for this process
70    int curSchedGroup;          // Currently desired scheduling class
71    int setSchedGroup;          // Last set to background scheduling class
72    int trimMemoryLevel;        // Last selected memory trimming level
73    int memImportance;          // Importance constant computed from curAdj
74    boolean serviceb;           // Process currently is on the service B list
75    boolean keeping;            // Actively running code so don't kill due to that?
76    boolean setIsForeground;    // Running foreground UI when last set?
77    boolean hasActivities;      // Are there any activities running in this process?
78    boolean foregroundServices; // Running any services that are foreground?
79    boolean foregroundActivities; // Running any activities that are foreground?
80    boolean systemNoUi;         // This is a system process, but not currently showing UI.
81    boolean hasShownUi;         // Has UI been shown in this process since it was started?
82    boolean pendingUiClean;     // Want to clean up resources from showing UI?
83    boolean hasAboveClient;     // Bound using BIND_ABOVE_CLIENT, so want to be lower
84    boolean bad;                // True if disabled in the bad process list
85    boolean killedBackground;   // True when proc has been killed due to too many bg
86    String waitingToKill;       // Process is waiting to be killed when in the bg; reason
87    IBinder forcingToForeground;// Token that is forcing this process to be foreground
88    int adjSeq;                 // Sequence id for identifying oom_adj assignment cycles
89    int lruSeq;                 // Sequence id for identifying LRU update cycles
90    CompatibilityInfo compat;   // last used compatibility mode
91    IBinder.DeathRecipient deathRecipient; // Who is watching for the death.
92    ComponentName instrumentationClass;// class installed to instrument app
93    ApplicationInfo instrumentationInfo; // the application being instrumented
94    String instrumentationProfileFile; // where to save profiling
95    IInstrumentationWatcher instrumentationWatcher; // who is waiting
96    Bundle instrumentationArguments;// as given to us
97    ComponentName instrumentationResultClass;// copy of instrumentationClass
98    boolean usingWrapper;       // Set to true when process was launched with a wrapper attached
99    BroadcastRecord curReceiver;// receiver currently running in the app
100    long lastWakeTime;          // How long proc held wake lock at last check
101    long lastCpuTime;           // How long proc has run CPU at last check
102    long curCpuTime;            // How long proc has run CPU most recently
103    long lastRequestedGc;       // When we last asked the app to do a gc
104    long lastLowMemory;         // When we last told the app that memory is low
105    boolean reportLowMemory;    // Set to true when waiting to report low mem
106    boolean empty;              // Is this an empty background process?
107    boolean hidden;             // Is this a hidden process?
108    int lastPss;                // Last pss size reported by app.
109    String adjType;             // Debugging: primary thing impacting oom_adj.
110    int adjTypeCode;            // Debugging: adj code to report to app.
111    Object adjSource;           // Debugging: option dependent object.
112    int adjSourceOom;           // Debugging: oom_adj of adjSource's process.
113    Object adjTarget;           // Debugging: target component impacting oom_adj.
114
115    // contains HistoryRecord objects
116    final ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
117    // all ServiceRecord running in this process
118    final HashSet<ServiceRecord> services = new HashSet<ServiceRecord>();
119    // services that are currently executing code (need to remain foreground).
120    final HashSet<ServiceRecord> executingServices
121             = new HashSet<ServiceRecord>();
122    // All ConnectionRecord this process holds
123    final HashSet<ConnectionRecord> connections
124            = new HashSet<ConnectionRecord>();
125    // all IIntentReceivers that are registered from this process.
126    final HashSet<ReceiverList> receivers = new HashSet<ReceiverList>();
127    // class (String) -> ContentProviderRecord
128    final HashMap<String, ContentProviderRecord> pubProviders
129            = new HashMap<String, ContentProviderRecord>();
130    // All ContentProviderRecord process is using
131    final ArrayList<ContentProviderConnection> conProviders
132            = new ArrayList<ContentProviderConnection>();
133
134    boolean persistent;         // always keep this application running?
135    boolean crashing;           // are we in the process of crashing?
136    Dialog crashDialog;         // dialog being displayed due to crash.
137    boolean notResponding;      // does the app have a not responding dialog?
138    Dialog anrDialog;           // dialog being displayed due to app not resp.
139    boolean removed;            // has app package been removed from device?
140    boolean debugging;          // was app launched for debugging?
141    boolean waitedForDebugger;  // has process show wait for debugger dialog?
142    Dialog waitDialog;          // current wait for debugger dialog
143
144    String shortStringName;     // caching of toShortString() result.
145    String stringName;          // caching of toString() result.
146
147    // These reports are generated & stored when an app gets into an error condition.
148    // They will be "null" when all is OK.
149    ActivityManager.ProcessErrorStateInfo crashingReport;
150    ActivityManager.ProcessErrorStateInfo notRespondingReport;
151
152    // Who will be notified of the error. This is usually an activity in the
153    // app that installed the package.
154    ComponentName errorReportReceiver;
155
156    void dump(PrintWriter pw, String prefix) {
157        final long now = SystemClock.uptimeMillis();
158
159        pw.print(prefix); pw.print("user #"); pw.print(userId);
160                pw.print(" uid="); pw.print(info.uid);
161        if (uid != info.uid) {
162            pw.print(" ISOLATED uid="); pw.print(uid);
163        }
164        pw.println();
165        if (info.className != null) {
166            pw.print(prefix); pw.print("class="); pw.println(info.className);
167        }
168        if (info.manageSpaceActivityName != null) {
169            pw.print(prefix); pw.print("manageSpaceActivityName=");
170            pw.println(info.manageSpaceActivityName);
171        }
172        pw.print(prefix); pw.print("dir="); pw.print(info.sourceDir);
173                pw.print(" publicDir="); pw.print(info.publicSourceDir);
174                pw.print(" data="); pw.println(info.dataDir);
175        pw.print(prefix); pw.print("packageList="); pw.println(pkgList);
176        pw.print(prefix); pw.print("compat="); pw.println(compat);
177        if (instrumentationClass != null || instrumentationProfileFile != null
178                || instrumentationArguments != null) {
179            pw.print(prefix); pw.print("instrumentationClass=");
180                    pw.print(instrumentationClass);
181                    pw.print(" instrumentationProfileFile=");
182                    pw.println(instrumentationProfileFile);
183            pw.print(prefix); pw.print("instrumentationArguments=");
184                    pw.println(instrumentationArguments);
185            pw.print(prefix); pw.print("instrumentationInfo=");
186                    pw.println(instrumentationInfo);
187            if (instrumentationInfo != null) {
188                instrumentationInfo.dump(new PrintWriterPrinter(pw), prefix + "  ");
189            }
190        }
191        pw.print(prefix); pw.print("thread="); pw.print(thread);
192                pw.print(" curReceiver="); pw.println(curReceiver);
193        pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
194                pw.print(starting); pw.print(" lastPss="); pw.println(lastPss);
195        pw.print(prefix); pw.print("lastActivityTime=");
196                TimeUtils.formatDuration(lastActivityTime, now, pw);
197                pw.print(" lruWeight="); pw.print(lruWeight);
198                pw.print(" serviceb="); pw.print(serviceb);
199                pw.print(" keeping="); pw.print(keeping);
200                pw.print(" hidden="); pw.print(hidden);
201                pw.print(" empty="); pw.println(empty);
202        pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
203                pw.print(" hidden="); pw.print(hiddenAdj);
204                pw.print(" empty="); pw.print(emptyAdj);
205                pw.print(" curRaw="); pw.print(curRawAdj);
206                pw.print(" setRaw="); pw.print(setRawAdj);
207                pw.print(" nonStopping="); pw.print(nonStoppingAdj);
208                pw.print(" cur="); pw.print(curAdj);
209                pw.print(" set="); pw.println(setAdj);
210        pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup);
211                pw.print(" setSchedGroup="); pw.print(setSchedGroup);
212                pw.print(" systemNoUi="); pw.print(systemNoUi);
213                pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
214        pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
215                pw.print(" pendingUiClean="); pw.print(pendingUiClean);
216                pw.print(" hasAboveClient="); pw.println(hasAboveClient);
217        pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
218                pw.print(" foregroundServices="); pw.print(foregroundServices);
219                pw.print(" forcingToForeground="); pw.println(forcingToForeground);
220        pw.print(prefix); pw.print("persistent="); pw.print(persistent);
221                pw.print(" removed="); pw.print(removed);
222                pw.print(" hasActivities="); pw.print(hasActivities);
223                pw.print(" foregroundActivities="); pw.println(foregroundActivities);
224        pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
225                pw.print(" lruSeq="); pw.println(lruSeq);
226        if (!keeping) {
227            long wtime;
228            synchronized (batteryStats.getBatteryStats()) {
229                wtime = batteryStats.getBatteryStats().getProcessWakeTime(info.uid,
230                        pid, SystemClock.elapsedRealtime());
231            }
232            long timeUsed = wtime - lastWakeTime;
233            pw.print(prefix); pw.print("lastWakeTime="); pw.print(lastWakeTime);
234                    pw.print(" time used=");
235                    TimeUtils.formatDuration(timeUsed, pw); pw.println("");
236            pw.print(prefix); pw.print("lastCpuTime="); pw.print(lastCpuTime);
237                    pw.print(" time used=");
238                    TimeUtils.formatDuration(curCpuTime-lastCpuTime, pw); pw.println("");
239        }
240        pw.print(prefix); pw.print("lastRequestedGc=");
241                TimeUtils.formatDuration(lastRequestedGc, now, pw);
242                pw.print(" lastLowMemory=");
243                TimeUtils.formatDuration(lastLowMemory, now, pw);
244                pw.print(" reportLowMemory="); pw.println(reportLowMemory);
245        if (killedBackground || waitingToKill != null) {
246            pw.print(prefix); pw.print("killedBackground="); pw.print(killedBackground);
247                    pw.print(" waitingToKill="); pw.println(waitingToKill);
248        }
249        if (debugging || crashing || crashDialog != null || notResponding
250                || anrDialog != null || bad) {
251            pw.print(prefix); pw.print("debugging="); pw.print(debugging);
252                    pw.print(" crashing="); pw.print(crashing);
253                    pw.print(" "); pw.print(crashDialog);
254                    pw.print(" notResponding="); pw.print(notResponding);
255                    pw.print(" " ); pw.print(anrDialog);
256                    pw.print(" bad="); pw.print(bad);
257
258                    // crashing or notResponding is always set before errorReportReceiver
259                    if (errorReportReceiver != null) {
260                        pw.print(" errorReportReceiver=");
261                        pw.print(errorReportReceiver.flattenToShortString());
262                    }
263                    pw.println();
264        }
265        if (activities.size() > 0) {
266            pw.print(prefix); pw.println("Activities:");
267            for (int i=0; i<activities.size(); i++) {
268                pw.print(prefix); pw.print("  - "); pw.println(activities.get(i));
269            }
270        }
271        if (services.size() > 0) {
272            pw.print(prefix); pw.println("Services:");
273            for (ServiceRecord sr : services) {
274                pw.print(prefix); pw.print("  - "); pw.println(sr);
275            }
276        }
277        if (executingServices.size() > 0) {
278            pw.print(prefix); pw.println("Executing Services:");
279            for (ServiceRecord sr : executingServices) {
280                pw.print(prefix); pw.print("  - "); pw.println(sr);
281            }
282        }
283        if (connections.size() > 0) {
284            pw.print(prefix); pw.println("Connections:");
285            for (ConnectionRecord cr : connections) {
286                pw.print(prefix); pw.print("  - "); pw.println(cr);
287            }
288        }
289        if (pubProviders.size() > 0) {
290            pw.print(prefix); pw.println("Published Providers:");
291            for (HashMap.Entry<String, ContentProviderRecord> ent : pubProviders.entrySet()) {
292                pw.print(prefix); pw.print("  - "); pw.println(ent.getKey());
293                pw.print(prefix); pw.print("    -> "); pw.println(ent.getValue());
294            }
295        }
296        if (conProviders.size() > 0) {
297            pw.print(prefix); pw.println("Connected Providers:");
298            for (int i=0; i<conProviders.size(); i++) {
299                pw.print(prefix); pw.print("  - "); pw.println(conProviders.get(i).toShortString());
300            }
301        }
302        if (receivers.size() > 0) {
303            pw.print(prefix); pw.println("Receivers:");
304            for (ReceiverList rl : receivers) {
305                pw.print(prefix); pw.print("  - "); pw.println(rl);
306            }
307        }
308    }
309
310    ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread,
311            ApplicationInfo _info, String _processName, int _uid) {
312        batteryStats = _batteryStats;
313        info = _info;
314        isolated = _info.uid != _uid;
315        uid = _uid;
316        userId = UserHandle.getUserId(_uid);
317        processName = _processName;
318        pkgList.add(_info.packageName);
319        thread = _thread;
320        maxAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
321        hiddenAdj = emptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
322        curRawAdj = setRawAdj = -100;
323        curAdj = setAdj = -100;
324        persistent = false;
325        removed = false;
326    }
327
328    public void setPid(int _pid) {
329        pid = _pid;
330        shortStringName = null;
331        stringName = null;
332    }
333
334    /**
335     * This method returns true if any of the activities within the process record are interesting
336     * to the user. See HistoryRecord.isInterestingToUserLocked()
337     */
338    public boolean isInterestingToUserLocked() {
339        final int size = activities.size();
340        for (int i = 0 ; i < size ; i++) {
341            ActivityRecord r = activities.get(i);
342            if (r.isInterestingToUserLocked()) {
343                return true;
344            }
345        }
346        return false;
347    }
348
349    public void stopFreezingAllLocked() {
350        int i = activities.size();
351        while (i > 0) {
352            i--;
353            activities.get(i).stopFreezingScreenLocked(true);
354        }
355    }
356
357    public void unlinkDeathRecipient() {
358        if (deathRecipient != null && thread != null) {
359            thread.asBinder().unlinkToDeath(deathRecipient, 0);
360        }
361        deathRecipient = null;
362    }
363
364    void updateHasAboveClientLocked() {
365        hasAboveClient = false;
366        if (connections.size() > 0) {
367            for (ConnectionRecord cr : connections) {
368                if ((cr.flags&Context.BIND_ABOVE_CLIENT) != 0) {
369                    hasAboveClient = true;
370                    break;
371                }
372            }
373        }
374    }
375
376    public String toShortString() {
377        if (shortStringName != null) {
378            return shortStringName;
379        }
380        StringBuilder sb = new StringBuilder(128);
381        toShortString(sb);
382        return shortStringName = sb.toString();
383    }
384
385    void toShortString(StringBuilder sb) {
386        sb.append(pid);
387        sb.append(':');
388        sb.append(processName);
389        sb.append('/');
390        if (info.uid < Process.FIRST_APPLICATION_UID) {
391            sb.append(uid);
392        } else {
393            sb.append('u');
394            sb.append(userId);
395            sb.append('a');
396            sb.append(info.uid%Process.FIRST_APPLICATION_UID);
397            if (uid != info.uid) {
398                sb.append('i');
399                sb.append(UserHandle.getAppId(uid) - Process.FIRST_ISOLATED_UID);
400            }
401        }
402    }
403
404    public String toString() {
405        if (stringName != null) {
406            return stringName;
407        }
408        StringBuilder sb = new StringBuilder(128);
409        sb.append("ProcessRecord{");
410        sb.append(Integer.toHexString(System.identityHashCode(this)));
411        sb.append(' ');
412        toShortString(sb);
413        sb.append('}');
414        return stringName = sb.toString();
415    }
416
417    /*
418     *  Return true if package has been added false if not
419     */
420    public boolean addPackage(String pkg) {
421        if (!pkgList.contains(pkg)) {
422            pkgList.add(pkg);
423            return true;
424        }
425        return false;
426    }
427
428    /*
429     *  Delete all packages from list except the package indicated in info
430     */
431    public void resetPackageList() {
432        pkgList.clear();
433        pkgList.add(info.packageName);
434    }
435
436    public String[] getPackageList() {
437        int size = pkgList.size();
438        if (size == 0) {
439            return null;
440        }
441        String list[] = new String[size];
442        pkgList.toArray(list);
443        return list;
444    }
445}
446