• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.server.am;
18 
19 import com.android.internal.os.BatteryStatsImpl;
20 
21 import android.app.ActivityManager;
22 import android.app.Dialog;
23 import android.app.IApplicationThread;
24 import android.app.IInstrumentationWatcher;
25 import android.content.ComponentName;
26 import android.content.Context;
27 import android.content.pm.ApplicationInfo;
28 import android.content.res.CompatibilityInfo;
29 import android.os.Bundle;
30 import android.os.IBinder;
31 import android.os.Process;
32 import android.os.SystemClock;
33 import android.os.UserHandle;
34 import android.util.PrintWriterPrinter;
35 import android.util.TimeUtils;
36 
37 import java.io.PrintWriter;
38 import java.util.ArrayList;
39 import java.util.HashMap;
40 import java.util.HashSet;
41 
42 /**
43  * Full information about a particular process that
44  * is currently running.
45  */
46 class 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 
dump(PrintWriter pw, String prefix)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 
ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread, ApplicationInfo _info, String _processName, int _uid)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 
setPid(int _pid)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      */
isInterestingToUserLocked()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 
stopFreezingAllLocked()363     public void stopFreezingAllLocked() {
364         int i = activities.size();
365         while (i > 0) {
366             i--;
367             activities.get(i).stopFreezingScreenLocked(true);
368         }
369     }
370 
unlinkDeathRecipient()371     public void unlinkDeathRecipient() {
372         if (deathRecipient != null && thread != null) {
373             thread.asBinder().unlinkToDeath(deathRecipient, 0);
374         }
375         deathRecipient = null;
376     }
377 
updateHasAboveClientLocked()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 
toShortString()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 
toShortString(StringBuilder sb)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(UserHandle.getAppId(info.uid));
411             if (uid != info.uid) {
412                 sb.append('i');
413                 sb.append(UserHandle.getAppId(uid) - Process.FIRST_ISOLATED_UID);
414             }
415         }
416     }
417 
toString()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      */
addPackage(String pkg)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      */
resetPackageList()445     public void resetPackageList() {
446         pkgList.clear();
447         pkgList.add(info.packageName);
448     }
449 
getPackageList()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