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