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 static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
20 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
21 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
22 
23 import android.util.ArraySet;
24 import android.util.DebugUtils;
25 import android.util.EventLog;
26 import android.util.Slog;
27 import com.android.internal.app.procstats.ProcessStats;
28 import com.android.internal.app.procstats.ProcessState;
29 import com.android.internal.os.BatteryStatsImpl;
30 
31 import android.app.ActivityManager;
32 import android.app.Dialog;
33 import android.app.IApplicationThread;
34 import android.content.ComponentName;
35 import android.content.Context;
36 import android.content.pm.ApplicationInfo;
37 import android.content.res.CompatibilityInfo;
38 import android.os.Binder;
39 import android.os.IBinder;
40 import android.os.Process;
41 import android.os.RemoteException;
42 import android.os.SystemClock;
43 import android.os.Trace;
44 import android.os.UserHandle;
45 import android.util.ArrayMap;
46 import android.util.TimeUtils;
47 
48 import java.io.PrintWriter;
49 import java.util.ArrayList;
50 
51 /**
52  * Full information about a particular process that
53  * is currently running.
54  */
55 final class ProcessRecord {
56     private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessRecord" : TAG_AM;
57 
58     private final BatteryStatsImpl mBatteryStats; // where to collect runtime statistics
59     final ApplicationInfo info; // all about the first app in the process
60     final boolean isolated;     // true if this is a special isolated process
61     final int uid;              // uid of process; may be different from 'info' if isolated
62     final int userId;           // user of process.
63     final String processName;   // name of the process
64     // List of packages running in the process
65     final ArrayMap<String, ProcessStats.ProcessStateHolder> pkgList = new ArrayMap<>();
66     UidRecord uidRecord;        // overall state of process's uid.
67     ArraySet<String> pkgDeps;   // additional packages we have a dependency on
68     IApplicationThread thread;  // the actual proc...  may be null only if
69                                 // 'persistent' is true (in which case we
70                                 // are in the process of launching the app)
71     ProcessState baseProcessTracker;
72     BatteryStatsImpl.Uid.Proc curProcBatteryStats;
73     int pid;                    // The process of this application; 0 if none
74     String procStatFile;        // path to /proc/<pid>/stat
75     int[] gids;                 // The gids this process was launched with
76     String requiredAbi;         // The ABI this process was launched with
77     String instructionSet;      // The instruction set this process was launched with
78     boolean starting;           // True if the process is being started
79     long lastActivityTime;      // For managing the LRU list
80     long lastPssTime;           // Last time we retrieved PSS data
81     long nextPssTime;           // Next time we want to request PSS data
82     long lastStateTime;         // Last time setProcState changed
83     long initialIdlePss;        // Initial memory pss of process for idle maintenance.
84     long lastPss;               // Last computed memory pss.
85     long lastSwapPss;           // Last computed SwapPss.
86     long lastCachedPss;         // Last computed pss when in cached state.
87     long lastCachedSwapPss;     // Last computed SwapPss when in cached state.
88     int maxAdj;                 // Maximum OOM adjustment for this process
89     int curRawAdj;              // Current OOM unlimited adjustment for this process
90     int setRawAdj;              // Last set OOM unlimited adjustment for this process
91     int curAdj;                 // Current OOM adjustment for this process
92     int setAdj;                 // Last set OOM adjustment for this process
93     int verifiedAdj;            // The last adjustment that was verified as actually being set
94     int curSchedGroup;          // Currently desired scheduling class
95     int setSchedGroup;          // Last set to background scheduling class
96     int vrThreadTid;            // Thread currently set for VR scheduling
97     int trimMemoryLevel;        // Last selected memory trimming level
98     int curProcState = PROCESS_STATE_NONEXISTENT; // Currently computed process state
99     int repProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state
100     int setProcState = PROCESS_STATE_NONEXISTENT; // Last set process state in process tracker
101     int pssProcState = PROCESS_STATE_NONEXISTENT; // Currently requesting pss for
102     int savedPriority;          // Previous priority value if we're switching to non-SCHED_OTHER
103     int renderThreadTid;        // TID for RenderThread
104     boolean serviceb;           // Process currently is on the service B list
105     boolean serviceHighRam;     // We are forcing to service B list due to its RAM use
106     boolean notCachedSinceIdle; // Has this process not been in a cached state since last idle?
107     boolean hasClientActivities;  // Are there any client services with activities?
108     boolean hasStartedServices; // Are there any started services running in this process?
109     boolean foregroundServices; // Running any services that are foreground?
110     boolean foregroundActivities; // Running any activities that are foreground?
111     boolean repForegroundActivities; // Last reported foreground activities.
112     boolean systemNoUi;         // This is a system process, but not currently showing UI.
113     boolean hasShownUi;         // Has UI been shown in this process since it was started?
114     boolean hasTopUi;           // Is this process currently showing a non-activity UI that the user
115                                 // is interacting with? E.g. The status bar when it is expanded, but
116                                 // not when it is minimized. When true the
117                                 // process will be set to use the ProcessList#SCHED_GROUP_TOP_APP
118                                 // scheduling group to boost performance.
119     boolean hasOverlayUi;       // Is the process currently showing a non-activity UI that
120                                 // overlays on-top of activity UIs on screen. E.g. display a window
121                                 // of type
122                                 // android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
123                                 // When true the process will oom adj score will be set to
124                                 // ProcessList#PERCEPTIBLE_APP_ADJ at minimum to reduce the chance
125                                 // of the process getting killed.
126     boolean pendingUiClean;     // Want to clean up resources from showing UI?
127     boolean hasAboveClient;     // Bound using BIND_ABOVE_CLIENT, so want to be lower
128     boolean treatLikeActivity;  // Bound using BIND_TREAT_LIKE_ACTIVITY
129     boolean bad;                // True if disabled in the bad process list
130     boolean killedByAm;         // True when proc has been killed by activity manager, not for RAM
131     boolean killed;             // True once we know the process has been killed
132     boolean procStateChanged;   // Keep track of whether we changed 'setAdj'.
133     boolean reportedInteraction;// Whether we have told usage stats about it being an interaction
134     boolean unlocked;           // True when proc was started in user unlocked state
135     long interactionEventTime;  // The time we sent the last interaction event
136     long fgInteractionTime;     // When we became foreground for interaction purposes
137     String waitingToKill;       // Process is waiting to be killed when in the bg, and reason
138     Object forcingToImportant;  // Token that is forcing this process to be important
139     int adjSeq;                 // Sequence id for identifying oom_adj assignment cycles
140     int lruSeq;                 // Sequence id for identifying LRU update cycles
141     CompatibilityInfo compat;   // last used compatibility mode
142     IBinder.DeathRecipient deathRecipient; // Who is watching for the death.
143     ActiveInstrumentation instr;// Set to currently active instrumentation running in process
144     boolean usingWrapper;       // Set to true when process was launched with a wrapper attached
145     final ArraySet<BroadcastRecord> curReceivers = new ArraySet<BroadcastRecord>();// receivers currently running in the app
146     long lastWakeTime;          // How long proc held wake lock at last check
147     long lastCpuTime;           // How long proc has run CPU at last check
148     long curCpuTime;            // How long proc has run CPU most recently
149     long lastRequestedGc;       // When we last asked the app to do a gc
150     long lastLowMemory;         // When we last told the app that memory is low
151     long lastProviderTime;      // The last time someone else was using a provider in this process.
152     boolean reportLowMemory;    // Set to true when waiting to report low mem
153     boolean empty;              // Is this an empty background process?
154     boolean cached;             // Is this a cached process?
155     String adjType;             // Debugging: primary thing impacting oom_adj.
156     int adjTypeCode;            // Debugging: adj code to report to app.
157     Object adjSource;           // Debugging: option dependent object.
158     int adjSourceProcState;     // Debugging: proc state of adjSource's process.
159     Object adjTarget;           // Debugging: target component impacting oom_adj.
160     Runnable crashHandler;      // Optional local handler to be invoked in the process crash.
161 
162     // all activities running in the process
163     final ArrayList<ActivityRecord> activities = new ArrayList<>();
164     // all ServiceRecord running in this process
165     final ArraySet<ServiceRecord> services = new ArraySet<>();
166     // services that are currently executing code (need to remain foreground).
167     final ArraySet<ServiceRecord> executingServices = new ArraySet<>();
168     // All ConnectionRecord this process holds
169     final ArraySet<ConnectionRecord> connections = new ArraySet<>();
170     // all IIntentReceivers that are registered from this process.
171     final ArraySet<ReceiverList> receivers = new ArraySet<>();
172     // class (String) -> ContentProviderRecord
173     final ArrayMap<String, ContentProviderRecord> pubProviders = new ArrayMap<>();
174     // All ContentProviderRecord process is using
175     final ArrayList<ContentProviderConnection> conProviders = new ArrayList<>();
176 
177     boolean execServicesFg;     // do we need to be executing services in the foreground?
178     boolean persistent;         // always keep this application running?
179     boolean crashing;           // are we in the process of crashing?
180     Dialog crashDialog;         // dialog being displayed due to crash.
181     boolean forceCrashReport;   // suppress normal auto-dismiss of crash dialog & report UI?
182     boolean notResponding;      // does the app have a not responding dialog?
183     Dialog anrDialog;           // dialog being displayed due to app not resp.
184     boolean removed;            // has app package been removed from device?
185     boolean debugging;          // was app launched for debugging?
186     boolean waitedForDebugger;  // has process show wait for debugger dialog?
187     Dialog waitDialog;          // current wait for debugger dialog
188 
189     String shortStringName;     // caching of toShortString() result.
190     String stringName;          // caching of toString() result.
191 
192     // These reports are generated & stored when an app gets into an error condition.
193     // They will be "null" when all is OK.
194     ActivityManager.ProcessErrorStateInfo crashingReport;
195     ActivityManager.ProcessErrorStateInfo notRespondingReport;
196 
197     // Who will be notified of the error. This is usually an activity in the
198     // app that installed the package.
199     ComponentName errorReportReceiver;
200 
201     // Process is currently hosting a backup agent for backup or restore
202     public boolean inFullBackup;
203     // App is allowed to manage whitelists such as temporary Power Save mode whitelist.
204     boolean whitelistManager;
205 
dump(PrintWriter pw, String prefix)206     void dump(PrintWriter pw, String prefix) {
207         final long now = SystemClock.uptimeMillis();
208 
209         pw.print(prefix); pw.print("user #"); pw.print(userId);
210                 pw.print(" uid="); pw.print(info.uid);
211         if (uid != info.uid) {
212             pw.print(" ISOLATED uid="); pw.print(uid);
213         }
214         pw.print(" gids={");
215         if (gids != null) {
216             for (int gi=0; gi<gids.length; gi++) {
217                 if (gi != 0) pw.print(", ");
218                 pw.print(gids[gi]);
219 
220             }
221         }
222         pw.println("}");
223         pw.print(prefix); pw.print("requiredAbi="); pw.print(requiredAbi);
224                 pw.print(" instructionSet="); pw.println(instructionSet);
225         if (info.className != null) {
226             pw.print(prefix); pw.print("class="); pw.println(info.className);
227         }
228         if (info.manageSpaceActivityName != null) {
229             pw.print(prefix); pw.print("manageSpaceActivityName=");
230             pw.println(info.manageSpaceActivityName);
231         }
232         pw.print(prefix); pw.print("dir="); pw.print(info.sourceDir);
233                 pw.print(" publicDir="); pw.print(info.publicSourceDir);
234                 pw.print(" data="); pw.println(info.dataDir);
235         pw.print(prefix); pw.print("packageList={");
236         for (int i=0; i<pkgList.size(); i++) {
237             if (i > 0) pw.print(", ");
238             pw.print(pkgList.keyAt(i));
239         }
240         pw.println("}");
241         if (pkgDeps != null) {
242             pw.print(prefix); pw.print("packageDependencies={");
243             for (int i=0; i<pkgDeps.size(); i++) {
244                 if (i > 0) pw.print(", ");
245                 pw.print(pkgDeps.valueAt(i));
246             }
247             pw.println("}");
248         }
249         pw.print(prefix); pw.print("compat="); pw.println(compat);
250         if (instr != null) {
251             pw.print(prefix); pw.print("instr="); pw.println(instr);
252         }
253         pw.print(prefix); pw.print("thread="); pw.println(thread);
254         pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
255                 pw.println(starting);
256         pw.print(prefix); pw.print("lastActivityTime=");
257                 TimeUtils.formatDuration(lastActivityTime, now, pw);
258                 pw.print(" lastPssTime=");
259                 TimeUtils.formatDuration(lastPssTime, now, pw);
260                 pw.print(" nextPssTime=");
261                 TimeUtils.formatDuration(nextPssTime, now, pw);
262                 pw.println();
263         pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
264                 pw.print(" lruSeq="); pw.print(lruSeq);
265                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, lastPss*1024);
266                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, lastSwapPss*1024);
267                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, lastCachedPss*1024);
268                 pw.print(" lastCachedSwapPss="); DebugUtils.printSizeValue(pw, lastCachedSwapPss*1024);
269                 pw.println();
270         pw.print(prefix); pw.print("cached="); pw.print(cached);
271                 pw.print(" empty="); pw.println(empty);
272         if (serviceb) {
273             pw.print(prefix); pw.print("serviceb="); pw.print(serviceb);
274                     pw.print(" serviceHighRam="); pw.println(serviceHighRam);
275         }
276         if (notCachedSinceIdle) {
277             pw.print(prefix); pw.print("notCachedSinceIdle="); pw.print(notCachedSinceIdle);
278                     pw.print(" initialIdlePss="); pw.println(initialIdlePss);
279         }
280         pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
281                 pw.print(" curRaw="); pw.print(curRawAdj);
282                 pw.print(" setRaw="); pw.print(setRawAdj);
283                 pw.print(" cur="); pw.print(curAdj);
284                 pw.print(" set="); pw.println(setAdj);
285         pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup);
286                 pw.print(" setSchedGroup="); pw.print(setSchedGroup);
287                 pw.print(" systemNoUi="); pw.print(systemNoUi);
288                 pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
289         if (vrThreadTid != 0) {
290             pw.print(prefix); pw.print("vrThreadTid="); pw.println(vrThreadTid);
291         }
292         pw.print(prefix); pw.print("curProcState="); pw.print(curProcState);
293                 pw.print(" repProcState="); pw.print(repProcState);
294                 pw.print(" pssProcState="); pw.print(pssProcState);
295                 pw.print(" setProcState="); pw.print(setProcState);
296                 pw.print(" lastStateTime=");
297                 TimeUtils.formatDuration(lastStateTime, now, pw);
298                 pw.println();
299         if (hasShownUi || pendingUiClean || hasAboveClient || treatLikeActivity) {
300             pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
301                     pw.print(" pendingUiClean="); pw.print(pendingUiClean);
302                     pw.print(" hasAboveClient="); pw.print(hasAboveClient);
303                     pw.print(" treatLikeActivity="); pw.println(treatLikeActivity);
304         }
305         if (hasTopUi || hasOverlayUi) {
306             pw.print(prefix); pw.print("hasTopUi="); pw.print(hasTopUi);
307                     pw.print(" hasOverlayUi="); pw.println(hasOverlayUi);
308         }
309         if (foregroundServices || forcingToImportant != null) {
310             pw.print(prefix); pw.print("foregroundServices="); pw.print(foregroundServices);
311                     pw.print(" forcingToImportant="); pw.println(forcingToImportant);
312         }
313         if (reportedInteraction || fgInteractionTime != 0) {
314             pw.print(prefix); pw.print("reportedInteraction=");
315             pw.print(reportedInteraction);
316             if (interactionEventTime != 0) {
317                 pw.print(" time=");
318                 TimeUtils.formatDuration(interactionEventTime, SystemClock.elapsedRealtime(), pw);
319             }
320             if (fgInteractionTime != 0) {
321                 pw.print(" fgInteractionTime=");
322                 TimeUtils.formatDuration(fgInteractionTime, SystemClock.elapsedRealtime(), pw);
323             }
324             pw.println();
325         }
326         if (persistent || removed) {
327             pw.print(prefix); pw.print("persistent="); pw.print(persistent);
328                     pw.print(" removed="); pw.println(removed);
329         }
330         if (hasClientActivities || foregroundActivities || repForegroundActivities) {
331             pw.print(prefix); pw.print("hasClientActivities="); pw.print(hasClientActivities);
332                     pw.print(" foregroundActivities="); pw.print(foregroundActivities);
333                     pw.print(" (rep="); pw.print(repForegroundActivities); pw.println(")");
334         }
335         if (lastProviderTime > 0) {
336             pw.print(prefix); pw.print("lastProviderTime=");
337             TimeUtils.formatDuration(lastProviderTime, now, pw);
338             pw.println();
339         }
340         if (hasStartedServices) {
341             pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices);
342         }
343         if (setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
344             long wtime;
345             synchronized (mBatteryStats) {
346                 wtime = mBatteryStats.getProcessWakeTime(info.uid,
347                         pid, SystemClock.elapsedRealtime());
348             }
349             pw.print(prefix); pw.print("lastWakeTime="); pw.print(lastWakeTime);
350                     pw.print(" timeUsed=");
351                     TimeUtils.formatDuration(wtime-lastWakeTime, pw); pw.println("");
352             pw.print(prefix); pw.print("lastCpuTime="); pw.print(lastCpuTime);
353                     pw.print(" timeUsed=");
354                     TimeUtils.formatDuration(curCpuTime-lastCpuTime, pw); pw.println("");
355         }
356         pw.print(prefix); pw.print("lastRequestedGc=");
357                 TimeUtils.formatDuration(lastRequestedGc, now, pw);
358                 pw.print(" lastLowMemory=");
359                 TimeUtils.formatDuration(lastLowMemory, now, pw);
360                 pw.print(" reportLowMemory="); pw.println(reportLowMemory);
361         if (killed || killedByAm || waitingToKill != null) {
362             pw.print(prefix); pw.print("killed="); pw.print(killed);
363                     pw.print(" killedByAm="); pw.print(killedByAm);
364                     pw.print(" waitingToKill="); pw.println(waitingToKill);
365         }
366         if (debugging || crashing || crashDialog != null || notResponding
367                 || anrDialog != null || bad) {
368             pw.print(prefix); pw.print("debugging="); pw.print(debugging);
369                     pw.print(" crashing="); pw.print(crashing);
370                     pw.print(" "); pw.print(crashDialog);
371                     pw.print(" notResponding="); pw.print(notResponding);
372                     pw.print(" " ); pw.print(anrDialog);
373                     pw.print(" bad="); pw.print(bad);
374 
375                     // crashing or notResponding is always set before errorReportReceiver
376                     if (errorReportReceiver != null) {
377                         pw.print(" errorReportReceiver=");
378                         pw.print(errorReportReceiver.flattenToShortString());
379                     }
380                     pw.println();
381         }
382         if (whitelistManager) {
383             pw.print(prefix); pw.print("whitelistManager="); pw.println(whitelistManager);
384         }
385         if (activities.size() > 0) {
386             pw.print(prefix); pw.println("Activities:");
387             for (int i=0; i<activities.size(); i++) {
388                 pw.print(prefix); pw.print("  - "); pw.println(activities.get(i));
389             }
390         }
391         if (services.size() > 0) {
392             pw.print(prefix); pw.println("Services:");
393             for (int i=0; i<services.size(); i++) {
394                 pw.print(prefix); pw.print("  - "); pw.println(services.valueAt(i));
395             }
396         }
397         if (executingServices.size() > 0) {
398             pw.print(prefix); pw.print("Executing Services (fg=");
399             pw.print(execServicesFg); pw.println(")");
400             for (int i=0; i<executingServices.size(); i++) {
401                 pw.print(prefix); pw.print("  - "); pw.println(executingServices.valueAt(i));
402             }
403         }
404         if (connections.size() > 0) {
405             pw.print(prefix); pw.println("Connections:");
406             for (int i=0; i<connections.size(); i++) {
407                 pw.print(prefix); pw.print("  - "); pw.println(connections.valueAt(i));
408             }
409         }
410         if (pubProviders.size() > 0) {
411             pw.print(prefix); pw.println("Published Providers:");
412             for (int i=0; i<pubProviders.size(); i++) {
413                 pw.print(prefix); pw.print("  - "); pw.println(pubProviders.keyAt(i));
414                 pw.print(prefix); pw.print("    -> "); pw.println(pubProviders.valueAt(i));
415             }
416         }
417         if (conProviders.size() > 0) {
418             pw.print(prefix); pw.println("Connected Providers:");
419             for (int i=0; i<conProviders.size(); i++) {
420                 pw.print(prefix); pw.print("  - "); pw.println(conProviders.get(i).toShortString());
421             }
422         }
423         if (!curReceivers.isEmpty()) {
424             pw.print(prefix); pw.println("Current Receivers:");
425             for (int i=0; i < curReceivers.size(); i++) {
426                 pw.print(prefix); pw.print("  - "); pw.println(curReceivers.valueAt(i));
427             }
428         }
429         if (receivers.size() > 0) {
430             pw.print(prefix); pw.println("Receivers:");
431             for (int i=0; i<receivers.size(); i++) {
432                 pw.print(prefix); pw.print("  - "); pw.println(receivers.valueAt(i));
433             }
434         }
435     }
436 
ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info, String _processName, int _uid)437     ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info,
438             String _processName, int _uid) {
439         mBatteryStats = _batteryStats;
440         info = _info;
441         isolated = _info.uid != _uid;
442         uid = _uid;
443         userId = UserHandle.getUserId(_uid);
444         processName = _processName;
445         pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.versionCode));
446         maxAdj = ProcessList.UNKNOWN_ADJ;
447         curRawAdj = setRawAdj = ProcessList.INVALID_ADJ;
448         curAdj = setAdj = verifiedAdj = ProcessList.INVALID_ADJ;
449         persistent = false;
450         removed = false;
451         lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis();
452     }
453 
setPid(int _pid)454     public void setPid(int _pid) {
455         pid = _pid;
456         procStatFile = null;
457         shortStringName = null;
458         stringName = null;
459     }
460 
makeActive(IApplicationThread _thread, ProcessStatsService tracker)461     public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
462         if (thread == null) {
463             final ProcessState origBase = baseProcessTracker;
464             if (origBase != null) {
465                 origBase.setState(ProcessStats.STATE_NOTHING,
466                         tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList);
467                 origBase.makeInactive();
468             }
469             baseProcessTracker = tracker.getProcessStateLocked(info.packageName, uid,
470                     info.versionCode, processName);
471             baseProcessTracker.makeActive();
472             for (int i=0; i<pkgList.size(); i++) {
473                 ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
474                 if (holder.state != null && holder.state != origBase) {
475                     holder.state.makeInactive();
476                 }
477                 holder.state = tracker.getProcessStateLocked(pkgList.keyAt(i), uid,
478                         info.versionCode, processName);
479                 if (holder.state != baseProcessTracker) {
480                     holder.state.makeActive();
481                 }
482             }
483         }
484         thread = _thread;
485     }
486 
makeInactive(ProcessStatsService tracker)487     public void makeInactive(ProcessStatsService tracker) {
488         thread = null;
489         final ProcessState origBase = baseProcessTracker;
490         if (origBase != null) {
491             if (origBase != null) {
492                 origBase.setState(ProcessStats.STATE_NOTHING,
493                         tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList);
494                 origBase.makeInactive();
495             }
496             baseProcessTracker = null;
497             for (int i=0; i<pkgList.size(); i++) {
498                 ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
499                 if (holder.state != null && holder.state != origBase) {
500                     holder.state.makeInactive();
501                 }
502                 holder.state = null;
503             }
504         }
505     }
506 
507     /**
508      * This method returns true if any of the activities within the process record are interesting
509      * to the user. See HistoryRecord.isInterestingToUserLocked()
510      */
isInterestingToUserLocked()511     public boolean isInterestingToUserLocked() {
512         final int size = activities.size();
513         for (int i = 0 ; i < size ; i++) {
514             ActivityRecord r = activities.get(i);
515             if (r.isInterestingToUserLocked()) {
516                 return true;
517             }
518         }
519 
520         final int servicesSize = services.size();
521         for (int i = 0; i < servicesSize; i++) {
522             ServiceRecord r = services.valueAt(i);
523             if (r.isForeground) {
524                 return true;
525             }
526         }
527         return false;
528     }
529 
stopFreezingAllLocked()530     public void stopFreezingAllLocked() {
531         int i = activities.size();
532         while (i > 0) {
533             i--;
534             activities.get(i).stopFreezingScreenLocked(true);
535         }
536     }
537 
unlinkDeathRecipient()538     public void unlinkDeathRecipient() {
539         if (deathRecipient != null && thread != null) {
540             thread.asBinder().unlinkToDeath(deathRecipient, 0);
541         }
542         deathRecipient = null;
543     }
544 
updateHasAboveClientLocked()545     void updateHasAboveClientLocked() {
546         hasAboveClient = false;
547         for (int i=connections.size()-1; i>=0; i--) {
548             ConnectionRecord cr = connections.valueAt(i);
549             if ((cr.flags&Context.BIND_ABOVE_CLIENT) != 0) {
550                 hasAboveClient = true;
551                 break;
552             }
553         }
554     }
555 
modifyRawOomAdj(int adj)556     int modifyRawOomAdj(int adj) {
557         if (hasAboveClient) {
558             // If this process has bound to any services with BIND_ABOVE_CLIENT,
559             // then we need to drop its adjustment to be lower than the service's
560             // in order to honor the request.  We want to drop it by one adjustment
561             // level...  but there is special meaning applied to various levels so
562             // we will skip some of them.
563             if (adj < ProcessList.FOREGROUND_APP_ADJ) {
564                 // System process will not get dropped, ever
565             } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
566                 adj = ProcessList.VISIBLE_APP_ADJ;
567             } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
568                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
569             } else if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
570                 adj = ProcessList.CACHED_APP_MIN_ADJ;
571             } else if (adj < ProcessList.CACHED_APP_MAX_ADJ) {
572                 adj++;
573             }
574         }
575         return adj;
576     }
577 
scheduleCrash(String message)578     void scheduleCrash(String message) {
579         // Checking killedbyAm should keep it from showing the crash dialog if the process
580         // was already dead for a good / normal reason.
581         if (!killedByAm) {
582             if (thread != null) {
583                 if (pid == Process.myPid()) {
584                     Slog.w(TAG, "scheduleCrash: trying to crash system process!");
585                     return;
586                 }
587                 long ident = Binder.clearCallingIdentity();
588                 try {
589                     thread.scheduleCrash(message);
590                 } catch (RemoteException e) {
591                     // If it's already dead our work is done. If it's wedged just kill it.
592                     // We won't get the crash dialog or the error reporting.
593                     kill("scheduleCrash for '" + message + "' failed", true);
594                 } finally {
595                     Binder.restoreCallingIdentity(ident);
596                 }
597             }
598         }
599     }
600 
kill(String reason, boolean noisy)601     void kill(String reason, boolean noisy) {
602         if (!killedByAm) {
603             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "kill");
604             if (noisy) {
605                 Slog.i(TAG, "Killing " + toShortString() + " (adj " + setAdj + "): " + reason);
606             }
607             EventLog.writeEvent(EventLogTags.AM_KILL, userId, pid, processName, setAdj, reason);
608             Process.killProcessQuiet(pid);
609             ActivityManagerService.killProcessGroup(uid, pid);
610             if (!persistent) {
611                 killed = true;
612                 killedByAm = true;
613             }
614             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
615         }
616     }
617 
toShortString()618     public String toShortString() {
619         if (shortStringName != null) {
620             return shortStringName;
621         }
622         StringBuilder sb = new StringBuilder(128);
623         toShortString(sb);
624         return shortStringName = sb.toString();
625     }
626 
toShortString(StringBuilder sb)627     void toShortString(StringBuilder sb) {
628         sb.append(pid);
629         sb.append(':');
630         sb.append(processName);
631         sb.append('/');
632         if (info.uid < Process.FIRST_APPLICATION_UID) {
633             sb.append(uid);
634         } else {
635             sb.append('u');
636             sb.append(userId);
637             int appId = UserHandle.getAppId(info.uid);
638             if (appId >= Process.FIRST_APPLICATION_UID) {
639                 sb.append('a');
640                 sb.append(appId - Process.FIRST_APPLICATION_UID);
641             } else {
642                 sb.append('s');
643                 sb.append(appId);
644             }
645             if (uid != info.uid) {
646                 sb.append('i');
647                 sb.append(UserHandle.getAppId(uid) - Process.FIRST_ISOLATED_UID);
648             }
649         }
650     }
651 
toString()652     public String toString() {
653         if (stringName != null) {
654             return stringName;
655         }
656         StringBuilder sb = new StringBuilder(128);
657         sb.append("ProcessRecord{");
658         sb.append(Integer.toHexString(System.identityHashCode(this)));
659         sb.append(' ');
660         toShortString(sb);
661         sb.append('}');
662         return stringName = sb.toString();
663     }
664 
makeAdjReason()665     public String makeAdjReason() {
666         if (adjSource != null || adjTarget != null) {
667             StringBuilder sb = new StringBuilder(128);
668             sb.append(' ');
669             if (adjTarget instanceof ComponentName) {
670                 sb.append(((ComponentName)adjTarget).flattenToShortString());
671             } else if (adjTarget != null) {
672                 sb.append(adjTarget.toString());
673             } else {
674                 sb.append("{null}");
675             }
676             sb.append("<=");
677             if (adjSource instanceof ProcessRecord) {
678                 sb.append("Proc{");
679                 sb.append(((ProcessRecord)adjSource).toShortString());
680                 sb.append("}");
681             } else if (adjSource != null) {
682                 sb.append(adjSource.toString());
683             } else {
684                 sb.append("{null}");
685             }
686             return sb.toString();
687         }
688         return null;
689     }
690 
691     /*
692      *  Return true if package has been added false if not
693      */
addPackage(String pkg, int versionCode, ProcessStatsService tracker)694     public boolean addPackage(String pkg, int versionCode, ProcessStatsService tracker) {
695         if (!pkgList.containsKey(pkg)) {
696             ProcessStats.ProcessStateHolder holder = new ProcessStats.ProcessStateHolder(
697                     versionCode);
698             if (baseProcessTracker != null) {
699                 holder.state = tracker.getProcessStateLocked(
700                         pkg, uid, versionCode, processName);
701                 pkgList.put(pkg, holder);
702                 if (holder.state != baseProcessTracker) {
703                     holder.state.makeActive();
704                 }
705             } else {
706                 pkgList.put(pkg, holder);
707             }
708             return true;
709         }
710         return false;
711     }
712 
getSetAdjWithServices()713     public int getSetAdjWithServices() {
714         if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
715             if (hasStartedServices) {
716                 return ProcessList.SERVICE_B_ADJ;
717             }
718         }
719         return setAdj;
720     }
721 
forceProcessStateUpTo(int newState)722     public void forceProcessStateUpTo(int newState) {
723         if (repProcState > newState) {
724             curProcState = repProcState = newState;
725         }
726     }
727 
728     /*
729      *  Delete all packages from list except the package indicated in info
730      */
resetPackageList(ProcessStatsService tracker)731     public void resetPackageList(ProcessStatsService tracker) {
732         final int N = pkgList.size();
733         if (baseProcessTracker != null) {
734             long now = SystemClock.uptimeMillis();
735             baseProcessTracker.setState(ProcessStats.STATE_NOTHING,
736                     tracker.getMemFactorLocked(), now, pkgList);
737             if (N != 1) {
738                 for (int i=0; i<N; i++) {
739                     ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i);
740                     if (holder.state != null && holder.state != baseProcessTracker) {
741                         holder.state.makeInactive();
742                     }
743 
744                 }
745                 pkgList.clear();
746                 ProcessState ps = tracker.getProcessStateLocked(
747                         info.packageName, uid, info.versionCode, processName);
748                 ProcessStats.ProcessStateHolder holder = new ProcessStats.ProcessStateHolder(
749                         info.versionCode);
750                 holder.state = ps;
751                 pkgList.put(info.packageName, holder);
752                 if (ps != baseProcessTracker) {
753                     ps.makeActive();
754                 }
755             }
756         } else if (N != 1) {
757             pkgList.clear();
758             pkgList.put(info.packageName, new ProcessStats.ProcessStateHolder(info.versionCode));
759         }
760     }
761 
getPackageList()762     public String[] getPackageList() {
763         int size = pkgList.size();
764         if (size == 0) {
765             return null;
766         }
767         String list[] = new String[size];
768         for (int i=0; i<pkgList.size(); i++) {
769             list[i] = pkgList.keyAt(i);
770         }
771         return list;
772     }
773 }
774