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